// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package slides provides access to the Google Slides API.
//
// For product documentation, see: https://developers.google.com/slides/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/slides/v1"
//   ...
//   ctx := context.Background()
//   slidesService, err := slides.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   slidesService, err := slides.NewService(ctx, option.WithScopes(slides.SpreadsheetsReadonlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   slidesService, err := slides.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   slidesService, err := slides.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package slides // import "google.golang.org/api/slides/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "slides:v1"
const apiName = "slides"
const apiVersion = "v1"
const basePath = "https://slides.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, create, and delete all of your Google Drive files
	DriveScope = "https://www.googleapis.com/auth/drive"

	// View and manage Google Drive files and folders that you have opened
	// or created with this app
	DriveFileScope = "https://www.googleapis.com/auth/drive.file"

	// See and download all your Google Drive files
	DriveReadonlyScope = "https://www.googleapis.com/auth/drive.readonly"

	// View and manage your Google Slides presentations
	PresentationsScope = "https://www.googleapis.com/auth/presentations"

	// View your Google Slides presentations
	PresentationsReadonlyScope = "https://www.googleapis.com/auth/presentations.readonly"

	// See, edit, create, and delete your spreadsheets in Google Drive
	SpreadsheetsScope = "https://www.googleapis.com/auth/spreadsheets"

	// View your Google Spreadsheets
	SpreadsheetsReadonlyScope = "https://www.googleapis.com/auth/spreadsheets.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/drive",
		"https://www.googleapis.com/auth/drive.file",
		"https://www.googleapis.com/auth/drive.readonly",
		"https://www.googleapis.com/auth/presentations",
		"https://www.googleapis.com/auth/presentations.readonly",
		"https://www.googleapis.com/auth/spreadsheets",
		"https://www.googleapis.com/auth/spreadsheets.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Presentations = NewPresentationsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Presentations *PresentationsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewPresentationsService(s *Service) *PresentationsService {
	rs := &PresentationsService{s: s}
	rs.Pages = NewPresentationsPagesService(s)
	return rs
}

type PresentationsService struct {
	s *Service

	Pages *PresentationsPagesService
}

func NewPresentationsPagesService(s *Service) *PresentationsPagesService {
	rs := &PresentationsPagesService{s: s}
	return rs
}

type PresentationsPagesService struct {
	s *Service
}

// AffineTransform: AffineTransform uses a 3x3 matrix with an implied
// last row of [ 0 0 1 ]
// to transform source coordinates (x,y) into destination coordinates
// (x', y')
// according to:
//
//       x'  x  =   shear_y  scale_y  translate_y
//       1  [ 1 ]
//
// After transformation,
//
//      x' = scale_x * x + shear_x * y + translate_x;
//      y' = scale_y * y + shear_y * x + translate_y;
//
// This message is therefore composed of these six matrix elements.
type AffineTransform struct {
	// ScaleX: The X coordinate scaling element.
	ScaleX float64 `json:"scaleX,omitempty"`

	// ScaleY: The Y coordinate scaling element.
	ScaleY float64 `json:"scaleY,omitempty"`

	// ShearX: The X coordinate shearing element.
	ShearX float64 `json:"shearX,omitempty"`

	// ShearY: The Y coordinate shearing element.
	ShearY float64 `json:"shearY,omitempty"`

	// TranslateX: The X coordinate translation element.
	TranslateX float64 `json:"translateX,omitempty"`

	// TranslateY: The Y coordinate translation element.
	TranslateY float64 `json:"translateY,omitempty"`

	// Unit: The units for translate elements.
	//
	// Possible values:
	//   "UNIT_UNSPECIFIED" - The units are unknown.
	//   "EMU" - An English Metric Unit (EMU) is defined as 1/360,000 of a
	// centimeter
	// and thus there are 914,400 EMUs per inch, and 12,700 EMUs per point.
	//   "PT" - A point, 1/72 of an inch.
	Unit string `json:"unit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ScaleX") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ScaleX") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AffineTransform) MarshalJSON() ([]byte, error) {
	type NoMethod AffineTransform
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *AffineTransform) UnmarshalJSON(data []byte) error {
	type NoMethod AffineTransform
	var s1 struct {
		ScaleX     gensupport.JSONFloat64 `json:"scaleX"`
		ScaleY     gensupport.JSONFloat64 `json:"scaleY"`
		ShearX     gensupport.JSONFloat64 `json:"shearX"`
		ShearY     gensupport.JSONFloat64 `json:"shearY"`
		TranslateX gensupport.JSONFloat64 `json:"translateX"`
		TranslateY gensupport.JSONFloat64 `json:"translateY"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.ScaleX = float64(s1.ScaleX)
	s.ScaleY = float64(s1.ScaleY)
	s.ShearX = float64(s1.ShearX)
	s.ShearY = float64(s1.ShearY)
	s.TranslateX = float64(s1.TranslateX)
	s.TranslateY = float64(s1.TranslateY)
	return nil
}

// AutoText: A TextElement kind that represents auto text.
type AutoText struct {
	// Content: The rendered content of this auto text, if available.
	Content string `json:"content,omitempty"`

	// Style: The styling applied to this auto text.
	Style *TextStyle `json:"style,omitempty"`

	// Type: The type of this auto text.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An unspecified autotext type.
	//   "SLIDE_NUMBER" - Type for autotext that represents the current
	// slide number.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Content") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AutoText) MarshalJSON() ([]byte, error) {
	type NoMethod AutoText
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchUpdatePresentationRequest: Request message for
// PresentationsService.BatchUpdatePresentation.
type BatchUpdatePresentationRequest struct {
	// Requests: A list of updates to apply to the presentation.
	Requests []*Request `json:"requests,omitempty"`

	// WriteControl: Provides control over how write requests are executed.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Requests") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Requests") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *BatchUpdatePresentationRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BatchUpdatePresentationRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// BatchUpdatePresentationResponse: Response message from a batch
// update.
type BatchUpdatePresentationResponse struct {
	// PresentationId: The presentation the updates were applied to.
	PresentationId string `json:"presentationId,omitempty"`

	// Replies: The reply of the updates.  This maps 1:1 with the updates,
	// although
	// replies to some requests may be empty.
	Replies []*Response `json:"replies,omitempty"`

	// WriteControl: The updated write control after applying the request.
	WriteControl *WriteControl `json:"writeControl,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "PresentationId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PresentationId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *BatchUpdatePresentationResponse) MarshalJSON() ([]byte, error) {
	type NoMethod BatchUpdatePresentationResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Bullet: Describes the bullet of a paragraph.
type Bullet struct {
	// BulletStyle: The paragraph specific text style applied to this
	// bullet.
	BulletStyle *TextStyle `json:"bulletStyle,omitempty"`

	// Glyph: The rendered bullet glyph for this paragraph.
	Glyph string `json:"glyph,omitempty"`

	// ListId: The ID of the list this paragraph belongs to.
	ListId string `json:"listId,omitempty"`

	// NestingLevel: The nesting level of this paragraph in the list.
	NestingLevel int64 `json:"nestingLevel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletStyle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Bullet) MarshalJSON() ([]byte, error) {
	type NoMethod Bullet
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ColorScheme: The palette of predefined colors for a page.
type ColorScheme struct {
	// Colors: The ThemeColorType and corresponding concrete color pairs.
	Colors []*ThemeColorPair `json:"colors,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Colors") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Colors") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ColorScheme) MarshalJSON() ([]byte, error) {
	type NoMethod ColorScheme
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ColorStop: A color and position in a gradient band.
type ColorStop struct {
	// Alpha: The alpha value of this color in the gradient band. Defaults
	// to 1.0,
	// fully opaque.
	Alpha float64 `json:"alpha,omitempty"`

	// Color: The color of the gradient stop.
	Color *OpaqueColor `json:"color,omitempty"`

	// Position: The relative position of the color stop in the gradient
	// band measured
	// in percentage. The value should be in the interval [0.0, 1.0].
	Position float64 `json:"position,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alpha") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alpha") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ColorStop) MarshalJSON() ([]byte, error) {
	type NoMethod ColorStop
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ColorStop) UnmarshalJSON(data []byte) error {
	type NoMethod ColorStop
	var s1 struct {
		Alpha    gensupport.JSONFloat64 `json:"alpha"`
		Position gensupport.JSONFloat64 `json:"position"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	s.Position = float64(s1.Position)
	return nil
}

// CreateImageRequest: Creates an image.
type CreateImageRequest struct {
	// ElementProperties: The element properties for the image.
	//
	// When the aspect ratio of the provided size does not match the image
	// aspect
	// ratio, the image is scaled and centered with respect to the size in
	// order
	// to maintain aspect ratio. The provided transform is applied after
	// this
	// operation.
	//
	// The PageElementProperties.size property is
	// optional. If you don't specify the size, the default size of the
	// image is
	// used.
	//
	// The PageElementProperties.transform property is
	// optional. If you don't specify a transform, the image will be placed
	// at the
	// top left corner of the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Url: The image URL.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateImageResponse: The result of creating an image.
type CreateImageResponse struct {
	// ObjectId: The object ID of the created image.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateImageResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateImageResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateLineRequest: Creates a line.
type CreateLineRequest struct {
	// Category: The category of the line to be created.
	//
	// The exact line type created is
	// determined based on the category and how it's routed to connect to
	// other
	// page elements.
	//
	// If you specify both a `category` and a `line_category`, the
	// `category`
	// takes precedence.
	//
	// If you do not specify a value for `category`, but specify a value
	// for
	// `line_category`, then the specified `line_category` value is
	// used.
	//
	// If you do not specify either, then STRAIGHT is used.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	Category string `json:"category,omitempty"`

	// ElementProperties: The element properties for the line.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// LineCategory: The category of the line to be
	// created.
	//
	// <b>Deprecated</b>: use `category` instead.
	//
	// The exact line type created is
	// determined based on the category and how it's routed to connect to
	// other
	// page elements.
	//
	// If you specify both a `category` and a `line_category`, the
	// `category`
	// takes precedence.
	//
	// Possible values:
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	// The is the default
	// category when one is not specified.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Category") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Category") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateLineRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateLineRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateLineResponse: The result of creating a line.
type CreateLineResponse struct {
	// ObjectId: The object ID of the created line.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateLineResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateLineResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateParagraphBulletsRequest: Creates bullets for all of the
// paragraphs that overlap with the given
// text index range.
//
// The nesting level of each paragraph will be determined by counting
// leading
// tabs in front of each paragraph. To avoid excess space between the
// bullet and
// the corresponding paragraph, these leading tabs are removed by this
// request.
// This may change the indices of parts of the text.
//
// If the paragraph immediately before paragraphs being updated is in a
// list
// with a matching preset, the paragraphs being updated are added to
// that
// preceding list.
type CreateParagraphBulletsRequest struct {
	// BulletPreset: The kinds of bullet glyphs to be used. Defaults to
	// the
	// `BULLET_DISC_CIRCLE_SQUARE` preset.
	//
	// Possible values:
	//   "BULLET_DISC_CIRCLE_SQUARE" - A bulleted list with a `DISC`,
	// `CIRCLE` and `SQUARE` bullet glyph for the
	// first 3 list nesting levels.
	//   "BULLET_DIAMONDX_ARROW3D_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `ARROW3D` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_CHECKBOX" - A bulleted list with `CHECKBOX` bullet glyphs
	// for all list nesting levels.
	//   "BULLET_ARROW_DIAMOND_DISC" - A bulleted list with a `ARROW`,
	// `DIAMOND` and `DISC` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_STAR_CIRCLE_SQUARE" - A bulleted list with a `STAR`,
	// `CIRCLE` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_ARROW3D_CIRCLE_SQUARE" - A bulleted list with a `ARROW3D`,
	// `CIRCLE` and `SQUARE` bullet glyph for
	// the first 3 list nesting levels.
	//   "BULLET_LEFTTRIANGLE_DIAMOND_DISC" - A bulleted list with a
	// `LEFTTRIANGLE`, `DIAMOND` and `DISC` bullet glyph
	// for the first 3 list nesting levels.
	//   "BULLET_DIAMONDX_HOLLOWDIAMOND_SQUARE" - A bulleted list with a
	// `DIAMONDX`, `HOLLOWDIAMOND` and `SQUARE` bullet
	// glyph for the first 3 list nesting levels.
	//   "BULLET_DIAMOND_CIRCLE_SQUARE" - A bulleted list with a `DIAMOND`,
	// `CIRCLE` and `SQUARE` bullet glyph
	// for the first 3 list nesting levels.
	//   "NUMBERED_DIGIT_ALPHA_ROMAN" - A numbered list with `DIGIT`,
	// `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_DIGIT_ALPHA_ROMAN_PARENS" - A numbered list with `DIGIT`,
	// `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by parenthesis.
	//   "NUMBERED_DIGIT_NESTED" - A numbered list with `DIGIT` numeric
	// glyphs separated by periods, where
	// each nesting level uses the previous nesting level's glyph as a
	// prefix.
	// For example: '1.', '1.1.', '2.', '2.2.'.
	//   "NUMBERED_UPPERALPHA_ALPHA_ROMAN" - A numbered list with
	// `UPPERALPHA`, `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_UPPERROMAN_UPPERALPHA_DIGIT" - A numbered list with
	// `UPPERROMAN`, `UPPERALPHA` and `DIGIT` numeric glyphs
	// for the first 3 list nesting levels, followed by periods.
	//   "NUMBERED_ZERODIGIT_ALPHA_ROMAN" - A numbered list with
	// `ZERODIGIT`, `ALPHA` and `ROMAN` numeric glyphs for
	// the first 3 list nesting levels, followed by periods.
	BulletPreset string `json:"bulletPreset,omitempty"`

	// CellLocation: The optional table cell location if the text to be
	// modified is in a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table containing the text to
	// add bullets to.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to apply the bullet presets to, based on
	// TextElement indexes.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletPreset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletPreset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateParagraphBulletsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateParagraphBulletsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateShapeRequest: Creates a new shape.
type CreateShapeRequest struct {
	// ElementProperties: The element properties for the shape.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	// If empty, a unique identifier will be generated.
	ObjectId string `json:"objectId,omitempty"`

	// ShapeType: The shape type.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The shape type that is not predefined.
	//   "TEXT_BOX" - Text box shape.
	//   "RECTANGLE" - Rectangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'rect'.
	//   "ROUND_RECTANGLE" - Round corner rectangle shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'roundRect'
	//   "ELLIPSE" - Ellipse shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ellipse'
	//   "ARC" - Curved arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'arc'
	//   "BENT_ARROW" - Bent arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentArrow'
	//   "BENT_UP_ARROW" - Bent up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentUpArrow'
	//   "BEVEL" - Bevel shape. Corresponds to ECMA-376 ST_ShapeType 'bevel'
	//   "BLOCK_ARC" - Block arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'blockArc'
	//   "BRACE_PAIR" - Brace pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracePair'
	//   "BRACKET_PAIR" - Bracket pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracketPair'
	//   "CAN" - Can shape. Corresponds to ECMA-376 ST_ShapeType 'can'
	//   "CHEVRON" - Chevron shape. Corresponds to ECMA-376 ST_ShapeType
	// 'chevron'
	//   "CHORD" - Chord shape. Corresponds to ECMA-376 ST_ShapeType 'chord'
	//   "CLOUD" - Cloud shape. Corresponds to ECMA-376 ST_ShapeType 'cloud'
	//   "CORNER" - Corner shape. Corresponds to ECMA-376 ST_ShapeType
	// 'corner'
	//   "CUBE" - Cube shape. Corresponds to ECMA-376 ST_ShapeType 'cube'
	//   "CURVED_DOWN_ARROW" - Curved down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedDownArrow'
	//   "CURVED_LEFT_ARROW" - Curved left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedLeftArrow'
	//   "CURVED_RIGHT_ARROW" - Curved right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedRightArrow'
	//   "CURVED_UP_ARROW" - Curved up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'curvedUpArrow'
	//   "DECAGON" - Decagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'decagon'
	//   "DIAGONAL_STRIPE" - Diagonal stripe shape. Corresponds to ECMA-376
	// ST_ShapeType 'diagStripe'
	//   "DIAMOND" - Diamond shape. Corresponds to ECMA-376 ST_ShapeType
	// 'diamond'
	//   "DODECAGON" - Dodecagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'dodecagon'
	//   "DONUT" - Donut shape. Corresponds to ECMA-376 ST_ShapeType 'donut'
	//   "DOUBLE_WAVE" - Double wave shape. Corresponds to ECMA-376
	// ST_ShapeType 'doubleWave'
	//   "DOWN_ARROW" - Down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'downArrow'
	//   "DOWN_ARROW_CALLOUT" - Callout down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'downArrowCallout'
	//   "FOLDED_CORNER" - Folded corner shape. Corresponds to ECMA-376
	// ST_ShapeType 'foldedCorner'
	//   "FRAME" - Frame shape. Corresponds to ECMA-376 ST_ShapeType 'frame'
	//   "HALF_FRAME" - Half frame shape. Corresponds to ECMA-376
	// ST_ShapeType 'halfFrame'
	//   "HEART" - Heart shape. Corresponds to ECMA-376 ST_ShapeType 'heart'
	//   "HEPTAGON" - Heptagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'heptagon'
	//   "HEXAGON" - Hexagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'hexagon'
	//   "HOME_PLATE" - Home plate shape. Corresponds to ECMA-376
	// ST_ShapeType 'homePlate'
	//   "HORIZONTAL_SCROLL" - Horizontal scroll shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'horizontalScroll'
	//   "IRREGULAR_SEAL_1" - Irregular seal 1 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal1'
	//   "IRREGULAR_SEAL_2" - Irregular seal 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal2'
	//   "LEFT_ARROW" - Left arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftArrow'
	//   "LEFT_ARROW_CALLOUT" - Callout left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftArrowCallout'
	//   "LEFT_BRACE" - Left brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBrace'
	//   "LEFT_BRACKET" - Left bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBracket'
	//   "LEFT_RIGHT_ARROW" - Left right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightArrow'
	//   "LEFT_RIGHT_ARROW_CALLOUT" - Callout left right arrow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'leftRightArrowCallout'
	//   "LEFT_RIGHT_UP_ARROW" - Left right up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightUpArrow'
	//   "LEFT_UP_ARROW" - Left up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftUpArrow'
	//   "LIGHTNING_BOLT" - Lightning bolt shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'lightningBolt'
	//   "MATH_DIVIDE" - Divide math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathDivide'
	//   "MATH_EQUAL" - Equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathEqual'
	//   "MATH_MINUS" - Minus math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMinus'
	//   "MATH_MULTIPLY" - Multiply math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMultiply'
	//   "MATH_NOT_EQUAL" - Not equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathNotEqual'
	//   "MATH_PLUS" - Plus math shape. Corresponds to ECMA-376 ST_ShapeType
	// 'mathPlus'
	//   "MOON" - Moon shape. Corresponds to ECMA-376 ST_ShapeType 'moon'
	//   "NO_SMOKING" - No smoking shape. Corresponds to ECMA-376
	// ST_ShapeType 'noSmoking'
	//   "NOTCHED_RIGHT_ARROW" - Notched right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'notchedRightArrow'
	//   "OCTAGON" - Octagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'octagon'
	//   "PARALLELOGRAM" - Parallelogram shape. Corresponds to ECMA-376
	// ST_ShapeType 'parallelogram'
	//   "PENTAGON" - Pentagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'pentagon'
	//   "PIE" - Pie shape. Corresponds to ECMA-376 ST_ShapeType 'pie'
	//   "PLAQUE" - Plaque shape. Corresponds to ECMA-376 ST_ShapeType
	// 'plaque'
	//   "PLUS" - Plus shape. Corresponds to ECMA-376 ST_ShapeType 'plus'
	//   "QUAD_ARROW" - Quad-arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'quadArrow'
	//   "QUAD_ARROW_CALLOUT" - Callout quad-arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'quadArrowCallout'
	//   "RIBBON" - Ribbon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon'
	//   "RIBBON_2" - Ribbon 2 shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon2'
	//   "RIGHT_ARROW" - Right arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightArrow'
	//   "RIGHT_ARROW_CALLOUT" - Callout right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'rightArrowCallout'
	//   "RIGHT_BRACE" - Right brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBrace'
	//   "RIGHT_BRACKET" - Right bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBracket'
	//   "ROUND_1_RECTANGLE" - One round corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'round1Rect'
	//   "ROUND_2_DIAGONAL_RECTANGLE" - Two diagonal round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2DiagRect'
	//   "ROUND_2_SAME_RECTANGLE" - Two same-side round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2SameRect'
	//   "RIGHT_TRIANGLE" - Right triangle shape. Corresponds to ECMA-376
	// ST_ShapeType 'rtTriangle'
	//   "SMILEY_FACE" - Smiley face shape. Corresponds to ECMA-376
	// ST_ShapeType 'smileyFace'
	//   "SNIP_1_RECTANGLE" - One snip corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'snip1Rect'
	//   "SNIP_2_DIAGONAL_RECTANGLE" - Two diagonal snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2DiagRect'
	//   "SNIP_2_SAME_RECTANGLE" - Two same-side snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2SameRect'
	//   "SNIP_ROUND_RECTANGLE" - One snip one round corner rectangle shape.
	// Corresponds to ECMA-376
	// ST_ShapeType 'snipRoundRect'
	//   "STAR_10" - Ten pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star10'
	//   "STAR_12" - Twelve pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star12'
	//   "STAR_16" - Sixteen pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star16'
	//   "STAR_24" - Twenty four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star24'
	//   "STAR_32" - Thirty two pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star32'
	//   "STAR_4" - Four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star4'
	//   "STAR_5" - Five pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star5'
	//   "STAR_6" - Six pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star6'
	//   "STAR_7" - Seven pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star7'
	//   "STAR_8" - Eight pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star8'
	//   "STRIPED_RIGHT_ARROW" - Striped right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'stripedRightArrow'
	//   "SUN" - Sun shape. Corresponds to ECMA-376 ST_ShapeType 'sun'
	//   "TRAPEZOID" - Trapezoid shape. Corresponds to ECMA-376 ST_ShapeType
	// 'trapezoid'
	//   "TRIANGLE" - Triangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'triangle'
	//   "UP_ARROW" - Up arrow shape. Corresponds to ECMA-376 ST_ShapeType
	// 'upArrow'
	//   "UP_ARROW_CALLOUT" - Callout up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'upArrowCallout'
	//   "UP_DOWN_ARROW" - Up down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'upDownArrow'
	//   "UTURN_ARROW" - U-turn arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'uturnArrow'
	//   "VERTICAL_SCROLL" - Vertical scroll shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'verticalScroll'
	//   "WAVE" - Wave shape. Corresponds to ECMA-376 ST_ShapeType 'wave'
	//   "WEDGE_ELLIPSE_CALLOUT" - Callout wedge ellipse shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'wedgeEllipseCallout'
	//   "WEDGE_RECTANGLE_CALLOUT" - Callout wedge rectangle shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRectCallout'
	//   "WEDGE_ROUND_RECTANGLE_CALLOUT" - Callout wedge round rectangle
	// shape. Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRoundRectCallout'
	//   "FLOW_CHART_ALTERNATE_PROCESS" - Alternate process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartAlternateProcess'
	//   "FLOW_CHART_COLLATE" - Collate flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartCollate'
	//   "FLOW_CHART_CONNECTOR" - Connector flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartConnector'
	//   "FLOW_CHART_DECISION" - Decision flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDecision'
	//   "FLOW_CHART_DELAY" - Delay flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartDelay'
	//   "FLOW_CHART_DISPLAY" - Display flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartDisplay'
	//   "FLOW_CHART_DOCUMENT" - Document flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDocument'
	//   "FLOW_CHART_EXTRACT" - Extract flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartExtract'
	//   "FLOW_CHART_INPUT_OUTPUT" - Input output flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartInputOutput'
	//   "FLOW_CHART_INTERNAL_STORAGE" - Internal storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartInternalStorage'
	//   "FLOW_CHART_MAGNETIC_DISK" - Magnetic disk flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDisk'
	//   "FLOW_CHART_MAGNETIC_DRUM" - Magnetic drum flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDrum'
	//   "FLOW_CHART_MAGNETIC_TAPE" - Magnetic tape flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticTape'
	//   "FLOW_CHART_MANUAL_INPUT" - Manual input flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartManualInput'
	//   "FLOW_CHART_MANUAL_OPERATION" - Manual operation flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartManualOperation'
	//   "FLOW_CHART_MERGE" - Merge flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartMerge'
	//   "FLOW_CHART_MULTIDOCUMENT" - Multi-document flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMultidocument'
	//   "FLOW_CHART_OFFLINE_STORAGE" - Offline storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOfflineStorage'
	//   "FLOW_CHART_OFFPAGE_CONNECTOR" - Off-page connector flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOffpageConnector'
	//   "FLOW_CHART_ONLINE_STORAGE" - Online storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOnlineStorage'
	//   "FLOW_CHART_OR" - Or flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartOr'
	//   "FLOW_CHART_PREDEFINED_PROCESS" - Predefined process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartPredefinedProcess'
	//   "FLOW_CHART_PREPARATION" - Preparation flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPreparation'
	//   "FLOW_CHART_PROCESS" - Process flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartProcess'
	//   "FLOW_CHART_PUNCHED_CARD" - Punched card flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedCard'
	//   "FLOW_CHART_PUNCHED_TAPE" - Punched tape flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedTape'
	//   "FLOW_CHART_SORT" - Sort flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartSort'
	//   "FLOW_CHART_SUMMING_JUNCTION" - Summing junction flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartSummingJunction'
	//   "FLOW_CHART_TERMINATOR" - Terminator flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartTerminator'
	//   "ARROW_EAST" - East arrow shape.
	//   "ARROW_NORTH_EAST" - Northeast arrow shape.
	//   "ARROW_NORTH" - North arrow shape.
	//   "SPEECH" - Speech shape.
	//   "STARBURST" - Star burst shape.
	//   "TEARDROP" - Teardrop shape. Corresponds to ECMA-376 ST_ShapeType
	// 'teardrop'
	//   "ELLIPSE_RIBBON" - Ellipse ribbon shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'ellipseRibbon'
	//   "ELLIPSE_RIBBON_2" - Ellipse ribbon 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'ellipseRibbon2'
	//   "CLOUD_CALLOUT" - Callout cloud shape. Corresponds to ECMA-376
	// ST_ShapeType 'cloudCallout'
	//   "CUSTOM" - Custom shape.
	ShapeType string `json:"shapeType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateShapeRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateShapeRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateShapeResponse: The result of creating a shape.
type CreateShapeResponse struct {
	// ObjectId: The object ID of the created shape.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateShapeResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateShapeResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSheetsChartRequest: Creates an embedded Google Sheets
// chart.
//
// NOTE: Chart creation requires at least one of the
// spreadsheets.readonly,
// spreadsheets, drive.readonly, drive.file, or drive OAuth scopes.
type CreateSheetsChartRequest struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet.
	ChartId int64 `json:"chartId,omitempty"`

	// ElementProperties: The element properties for the chart.
	//
	// When the aspect ratio of the provided size does not match the chart
	// aspect
	// ratio, the chart is scaled and centered with respect to the size in
	// order
	// to maintain aspect ratio. The provided transform is applied after
	// this
	// operation.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// LinkingMode: The mode with which the chart is linked to the source
	// spreadsheet. When
	// not specified, the chart will be an image that is not linked.
	//
	// Possible values:
	//   "NOT_LINKED_IMAGE" - The chart is not associated with the source
	// spreadsheet and cannot be
	// updated. A chart that is not linked will be inserted as an image.
	//   "LINKED" - Linking the chart allows it to be updated, and other
	// collaborators will
	// see a link to the spreadsheet.
	LinkingMode string `json:"linkingMode,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If specified, the ID must be unique among all pages and page elements
	// in
	// the presentation. The ID should start with a word character
	// [a-zA-Z0-9_]
	// and then followed by any number of the following characters
	// [a-zA-Z0-9_-:].
	// The length of the ID should not be less than 5 or greater than 50.
	// If empty, a unique identifier will be generated.
	ObjectId string `json:"objectId,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSheetsChartResponse: The result of creating an embedded Google
// Sheets chart.
type CreateSheetsChartResponse struct {
	// ObjectId: The object ID of the created chart.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSheetsChartResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSheetsChartResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSlideRequest: Creates a new slide.
type CreateSlideRequest struct {
	// InsertionIndex: The optional zero-based index indicating where to
	// insert the slides.
	//
	// If you don't specify an index, the new slide is created at the end.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// PlaceholderIdMappings: An optional list of object ID mappings from
	// the placeholder(s) on the layout to the placeholder(s)
	// that will be created on the new slide from that specified layout. Can
	// only
	// be used when `slide_layout_reference` is specified.
	PlaceholderIdMappings []*LayoutPlaceholderIdMapping `json:"placeholderIdMappings,omitempty"`

	// SlideLayoutReference: Layout reference of the slide to be inserted,
	// based on the *current
	// master*, which is one of the following:
	//
	// - The master of the previous slide index.
	// - The master of the first slide, if the insertion_index is zero.
	// - The first master in the presentation, if there are no slides.
	//
	// If the LayoutReference is not found in the current master, a 400
	// bad
	// request error is returned.
	//
	// If you don't specify a layout reference, then the new slide will use
	// the
	// predefined layout `BLANK`.
	SlideLayoutReference *LayoutReference `json:"slideLayoutReference,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InsertionIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InsertionIndex") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateSlideRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSlideRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateSlideResponse: The result of creating a slide.
type CreateSlideResponse struct {
	// ObjectId: The object ID of the created slide.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateSlideResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateSlideResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateTableRequest: Creates a new table.
type CreateTableRequest struct {
	// Columns: Number of columns in the table.
	Columns int64 `json:"columns,omitempty"`

	// ElementProperties: The element properties for the table.
	//
	// The table will be created at the provided size, subject to a minimum
	// size.
	// If no size is provided, the table will be automatically sized.
	//
	// Table transforms must have a scale of 1 and no shear components. If
	// no
	// transform is provided, the table will be centered on the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Rows: Number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Columns") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateTableRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateTableRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateTableResponse: The result of creating a table.
type CreateTableResponse struct {
	// ObjectId: The object ID of the created table.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateTableResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateTableResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateVideoRequest: Creates a video.
//
// NOTE: Creating a video from Google Drive requires that the requesting
// app
// have at least one of the drive, drive.readonly, or drive.file OAuth
// scopes.
type CreateVideoRequest struct {
	// ElementProperties: The element properties for the video.
	//
	// The PageElementProperties.size property is
	// optional. If you don't specify a size, a default size is chosen by
	// the
	// server.
	//
	// The PageElementProperties.transform property is
	// optional. The transform must not have shear components.
	// If you don't specify a transform, the video will be placed at the top
	// left
	// corner of the page.
	ElementProperties *PageElementProperties `json:"elementProperties,omitempty"`

	// Id: The video source's unique identifier for this video.
	//
	// e.g. For YouTube video
	// https://www.youtube.com/watch?v=7U3axjORYZ0,
	// the ID is 7U3axjORYZ0. For a Google Drive
	// video
	// https://drive.google.com/file/d/1xCgQLFTJi5_Xl8DgW_lcUYq5e-q6Hi5
	// Q the ID
	// is 1xCgQLFTJi5_Xl8DgW_lcUYq5e-q6Hi5Q.
	Id string `json:"id,omitempty"`

	// ObjectId: A user-supplied object ID.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// Source: The video source.
	//
	// Possible values:
	//   "SOURCE_UNSPECIFIED" - The video source is unspecified.
	//   "YOUTUBE" - The video source is YouTube.
	//   "DRIVE" - The video source is Google Drive.
	Source string `json:"source,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ElementProperties")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ElementProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *CreateVideoRequest) MarshalJSON() ([]byte, error) {
	type NoMethod CreateVideoRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CreateVideoResponse: The result of creating a video.
type CreateVideoResponse struct {
	// ObjectId: The object ID of the created video.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CreateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CreateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CropProperties: The crop properties of an object enclosed in a
// container. For example, an
// Image.
//
// The crop properties is represented by the offsets of four edges which
// define
// a crop rectangle. The offsets are measured in percentage from
// the
// corresponding edges of the object's original bounding rectangle
// towards
// inside, relative to the object's original dimensions.
//
// - If the offset is in the interval (0, 1), the corresponding edge of
// crop
// rectangle is positioned inside of the object's original bounding
// rectangle.
// - If the offset is negative or greater than 1, the corresponding edge
// of crop
// rectangle is positioned outside of the object's original bounding
// rectangle.
// - If the left edge of the crop rectangle is on the right side of its
// right
// edge, the object will be flipped horizontally.
// - If the top edge of the crop rectangle is below its bottom edge, the
// object
// will be flipped vertically.
// - If all offsets and rotation angle is 0, the object is not
// cropped.
//
// After cropping, the content in the crop rectangle will be stretched
// to fit
// its container.
type CropProperties struct {
	// Angle: The rotation angle of the crop window around its center, in
	// radians.
	// Rotation angle is applied after the offset.
	Angle float64 `json:"angle,omitempty"`

	// BottomOffset: The offset specifies the bottom edge of the crop
	// rectangle that is located
	// above the original bounding rectangle bottom edge, relative to the
	// object's
	// original height.
	BottomOffset float64 `json:"bottomOffset,omitempty"`

	// LeftOffset: The offset specifies the left edge of the crop rectangle
	// that is located to
	// the right of the original bounding rectangle left edge, relative to
	// the
	// object's original width.
	LeftOffset float64 `json:"leftOffset,omitempty"`

	// RightOffset: The offset specifies the right edge of the crop
	// rectangle that is located
	// to the left of the original bounding rectangle right edge, relative
	// to the
	// object's original width.
	RightOffset float64 `json:"rightOffset,omitempty"`

	// TopOffset: The offset specifies the top edge of the crop rectangle
	// that is located
	// below the original bounding rectangle top edge, relative to the
	// object's
	// original height.
	TopOffset float64 `json:"topOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Angle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Angle") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CropProperties) MarshalJSON() ([]byte, error) {
	type NoMethod CropProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *CropProperties) UnmarshalJSON(data []byte) error {
	type NoMethod CropProperties
	var s1 struct {
		Angle        gensupport.JSONFloat64 `json:"angle"`
		BottomOffset gensupport.JSONFloat64 `json:"bottomOffset"`
		LeftOffset   gensupport.JSONFloat64 `json:"leftOffset"`
		RightOffset  gensupport.JSONFloat64 `json:"rightOffset"`
		TopOffset    gensupport.JSONFloat64 `json:"topOffset"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Angle = float64(s1.Angle)
	s.BottomOffset = float64(s1.BottomOffset)
	s.LeftOffset = float64(s1.LeftOffset)
	s.RightOffset = float64(s1.RightOffset)
	s.TopOffset = float64(s1.TopOffset)
	return nil
}

// DeleteObjectRequest: Deletes an object, either pages or
// page elements, from the
// presentation.
type DeleteObjectRequest struct {
	// ObjectId: The object ID of the page or page element to delete.
	//
	// If after a delete operation a group contains
	// only 1 or no page elements, the group is also deleted.
	//
	// If a placeholder is deleted on a layout, any empty inheriting shapes
	// are
	// also deleted.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteObjectRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteParagraphBulletsRequest: Deletes bullets from all of the
// paragraphs that overlap with the given text
// index range.
//
// The nesting level of each paragraph will be visually preserved by
// adding
// indent to the start of the corresponding paragraph.
type DeleteParagraphBulletsRequest struct {
	// CellLocation: The optional table cell location if the text to be
	// modified is in a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table containing the text to
	// delete bullets
	// from.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to delete bullets from, based on
	// TextElement indexes.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteParagraphBulletsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteParagraphBulletsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTableColumnRequest: Deletes a column from a table.
type DeleteTableColumnRequest struct {
	// CellLocation: The reference table cell location from which a column
	// will be deleted.
	//
	// The column this cell spans will be deleted. If this is a merged
	// cell,
	// multiple columns will be deleted. If no columns remain in the table
	// after
	// this deletion, the whole table is deleted.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// TableObjectId: The table to delete columns from.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTableColumnRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTableColumnRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTableRowRequest: Deletes a row from a table.
type DeleteTableRowRequest struct {
	// CellLocation: The reference table cell location from which a row will
	// be deleted.
	//
	// The row this cell spans will be deleted. If this is a merged cell,
	// multiple
	// rows will be deleted. If no rows remain in the table after this
	// deletion,
	// the whole table is deleted.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// TableObjectId: The table to delete rows from.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTableRowRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTableRowRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeleteTextRequest: Deletes text from a shape or a table cell.
type DeleteTextRequest struct {
	// CellLocation: The optional table cell location if the text is to be
	// deleted from a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// ObjectId: The object ID of the shape or table from which the text
	// will be deleted.
	ObjectId string `json:"objectId,omitempty"`

	// TextRange: The range of text to delete, based on TextElement
	// indexes.
	//
	// There is always an implicit newline character at the end of a shape's
	// or
	// table cell's text that cannot be deleted. `Range.Type.ALL` will use
	// the
	// correct bounds, but care must be taken when specifying explicit
	// bounds for
	// range types `FROM_START_INDEX` and `FIXED_RANGE`. For example, if the
	// text
	// is "ABC", followed by an implicit newline, then the maximum value is
	// 2 for
	// `text_range.start_index` and 3 for `text_range.end_index`.
	//
	// Deleting text that crosses a paragraph boundary may result in
	// changes
	// to paragraph styles and lists as the two paragraphs are
	// merged.
	//
	// Ranges that include only one code unit of a surrogate pair are
	// expanded to
	// include both code units.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeleteTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DeleteTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Dimension: A magnitude in a single direction in the specified units.
type Dimension struct {
	// Magnitude: The magnitude.
	Magnitude float64 `json:"magnitude,omitempty"`

	// Unit: The units for magnitude.
	//
	// Possible values:
	//   "UNIT_UNSPECIFIED" - The units are unknown.
	//   "EMU" - An English Metric Unit (EMU) is defined as 1/360,000 of a
	// centimeter
	// and thus there are 914,400 EMUs per inch, and 12,700 EMUs per point.
	//   "PT" - A point, 1/72 of an inch.
	Unit string `json:"unit,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Magnitude") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Magnitude") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Dimension) MarshalJSON() ([]byte, error) {
	type NoMethod Dimension
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Dimension) UnmarshalJSON(data []byte) error {
	type NoMethod Dimension
	var s1 struct {
		Magnitude gensupport.JSONFloat64 `json:"magnitude"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Magnitude = float64(s1.Magnitude)
	return nil
}

// DuplicateObjectRequest: Duplicates a slide or page element.
//
// When duplicating a slide, the duplicate slide will be created
// immediately
// following the specified slide. When duplicating a page element, the
// duplicate
// will be placed on the same page at the same position as the original.
type DuplicateObjectRequest struct {
	// ObjectId: The ID of the object to duplicate.
	ObjectId string `json:"objectId,omitempty"`

	// ObjectIds: The object being duplicated may contain other objects, for
	// example when
	// duplicating a slide or a group page element. This map defines how the
	// IDs
	// of duplicated objects are generated: the keys are the IDs of the
	// original
	// objects and its values are the IDs that will be assigned to
	// the
	// corresponding duplicate object. The ID of the source object's
	// duplicate
	// may be specified in this map as well, using the same value of
	// the
	// `object_id` field as a key and the newly desired ID as the
	// value.
	//
	// All keys must correspond to existing IDs in the presentation. All
	// values
	// must be unique in the presentation and must start with an
	// alphanumeric
	// character or an underscore (matches regex `[a-zA-Z0-9_]`);
	// remaining
	// characters may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`). The length of the new ID must not be less than 5
	// or
	// greater than 50.
	//
	// If any IDs of source objects are omitted from the map, a new random
	// ID will
	// be assigned. If the map is empty or unset, all duplicate objects
	// will
	// receive a new random ID.
	ObjectIds map[string]string `json:"objectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DuplicateObjectRequest) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateObjectRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DuplicateObjectResponse: The response of duplicating an object.
type DuplicateObjectResponse struct {
	// ObjectId: The ID of the new duplicate object.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DuplicateObjectResponse) MarshalJSON() ([]byte, error) {
	type NoMethod DuplicateObjectResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Group: A PageElement kind representing a
// joined collection of PageElements.
type Group struct {
	// Children: The collection of elements in the group. The minimum size
	// of a group is 2.
	Children []*PageElement `json:"children,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Children") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Children") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Group) MarshalJSON() ([]byte, error) {
	type NoMethod Group
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupObjectsRequest: Groups objects to create an object group. For
// example, groups PageElements to create a Group on the same page as
// all the children.
type GroupObjectsRequest struct {
	// ChildrenObjectIds: The object IDs of the objects to group.
	//
	// Only page elements can be grouped. There should be at least two
	// page
	// elements on the same page that are not already in another group. Some
	// page
	// elements, such as videos, tables and placeholder shapes cannot be
	// grouped.
	ChildrenObjectIds []string `json:"childrenObjectIds,omitempty"`

	// GroupObjectId: A user-supplied object ID for the group to be
	// created.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	GroupObjectId string `json:"groupObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChildrenObjectIds")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChildrenObjectIds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GroupObjectsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GroupObjectsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GroupObjectsResponse: The result of grouping objects.
type GroupObjectsResponse struct {
	// ObjectId: The object ID of the created group.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GroupObjectsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GroupObjectsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Image: A PageElement kind representing an
// image.
type Image struct {
	// ContentUrl: An URL to an image with a default lifetime of 30
	// minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the image as the original requester. Access to
	// the
	// image may be lost if the presentation's sharing settings change.
	ContentUrl string `json:"contentUrl,omitempty"`

	// ImageProperties: The properties of the image.
	ImageProperties *ImageProperties `json:"imageProperties,omitempty"`

	// SourceUrl: The source URL is the URL used to insert the image. The
	// source URL can be
	// empty.
	SourceUrl string `json:"sourceUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Image) MarshalJSON() ([]byte, error) {
	type NoMethod Image
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ImageProperties: The properties of the Image.
type ImageProperties struct {
	// Brightness: The brightness effect of the image. The value should be
	// in the interval
	// [-1.0, 1.0], where 0 means no effect. This property is read-only.
	Brightness float64 `json:"brightness,omitempty"`

	// Contrast: The contrast effect of the image. The value should be in
	// the interval
	// [-1.0, 1.0], where 0 means no effect. This property is read-only.
	Contrast float64 `json:"contrast,omitempty"`

	// CropProperties: The crop properties of the image. If not set, the
	// image is not cropped.
	// This property is read-only.
	CropProperties *CropProperties `json:"cropProperties,omitempty"`

	// Link: The hyperlink destination of the image. If unset, there is no
	// link.
	Link *Link `json:"link,omitempty"`

	// Outline: The outline of the image. If not set, the image has no
	// outline.
	Outline *Outline `json:"outline,omitempty"`

	// Recolor: The recolor effect of the image. If not set, the image is
	// not recolored.
	// This property is read-only.
	Recolor *Recolor `json:"recolor,omitempty"`

	// Shadow: The shadow of the image. If not set, the image has no shadow.
	// This property
	// is read-only.
	Shadow *Shadow `json:"shadow,omitempty"`

	// Transparency: The transparency effect of the image. The value should
	// be in the interval
	// [0.0, 1.0], where 0 means no effect and 1 means completely
	// transparent.
	// This property is read-only.
	Transparency float64 `json:"transparency,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Brightness") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Brightness") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ImageProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ImageProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ImageProperties) UnmarshalJSON(data []byte) error {
	type NoMethod ImageProperties
	var s1 struct {
		Brightness   gensupport.JSONFloat64 `json:"brightness"`
		Contrast     gensupport.JSONFloat64 `json:"contrast"`
		Transparency gensupport.JSONFloat64 `json:"transparency"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Brightness = float64(s1.Brightness)
	s.Contrast = float64(s1.Contrast)
	s.Transparency = float64(s1.Transparency)
	return nil
}

// InsertTableColumnsRequest: Inserts columns into a table.
//
// Other columns in the table will be resized to fit the new column.
type InsertTableColumnsRequest struct {
	// CellLocation: The reference table cell location from which columns
	// will be inserted.
	//
	// A new column will be inserted to the left (or right) of the column
	// where
	// the reference cell is. If the reference cell is a merged cell, a
	// new
	// column will be inserted to the left (or right) of the merged cell.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertRight: Whether to insert new columns to the right of the
	// reference cell location.
	//
	// - `True`: insert to the right.
	// - `False`: insert to the left.
	InsertRight bool `json:"insertRight,omitempty"`

	// Number: The number of columns to be inserted. Maximum 20 per request.
	Number int64 `json:"number,omitempty"`

	// TableObjectId: The table to insert columns into.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTableColumnsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTableColumnsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertTableRowsRequest: Inserts rows into a table.
type InsertTableRowsRequest struct {
	// CellLocation: The reference table cell location from which rows will
	// be inserted.
	//
	// A new row will be inserted above (or below) the row where the
	// reference
	// cell is. If the reference cell is a merged cell, a new row will
	// be
	// inserted above (or below) the merged cell.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertBelow: Whether to insert new rows below the reference cell
	// location.
	//
	// - `True`: insert below the cell.
	// - `False`: insert above the cell.
	InsertBelow bool `json:"insertBelow,omitempty"`

	// Number: The number of rows to be inserted. Maximum 20 per request.
	Number int64 `json:"number,omitempty"`

	// TableObjectId: The table to insert rows into.
	TableObjectId string `json:"tableObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTableRowsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTableRowsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// InsertTextRequest: Inserts text into a shape or a table cell.
type InsertTextRequest struct {
	// CellLocation: The optional table cell location if the text is to be
	// inserted into a table
	// cell. If present, the object_id must refer to a table.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// InsertionIndex: The index where the text will be inserted, in Unicode
	// code units, based
	// on TextElement indexes.
	//
	// The index is zero-based and is computed from the start of the
	// string.
	// The index may be adjusted to prevent insertions inside Unicode
	// grapheme
	// clusters. In these cases, the text will be inserted immediately after
	// the
	// grapheme cluster.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// ObjectId: The object ID of the shape or table where the text will be
	// inserted.
	ObjectId string `json:"objectId,omitempty"`

	// Text: The text to be inserted.
	//
	// Inserting a newline character will implicitly create a
	// new
	// ParagraphMarker at that index.
	// The paragraph style of the new paragraph will be copied from the
	// paragraph
	// at the current insertion index, including lists and bullets.
	//
	// Text styles for inserted text will be determined automatically,
	// generally
	// preserving the styling of neighboring text. In most cases, the text
	// will be
	// added to the TextRun that exists at the
	// insertion index.
	//
	// Some control characters (U+0000-U+0008, U+000C-U+001F) and
	// characters
	// from the Unicode Basic Multilingual Plane Private Use Area
	// (U+E000-U+F8FF)
	// will be stripped out of the inserted text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *InsertTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod InsertTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutPlaceholderIdMapping: The user-specified ID mapping for a
// placeholder that will be created on a
// slide from a specified layout.
type LayoutPlaceholderIdMapping struct {
	// LayoutPlaceholder: The placeholder on a layout that will be applied
	// to a slide. Only type and index are needed. For example, a
	// predefined `TITLE_AND_BODY` layout may usually have a TITLE
	// placeholder
	// with index 0 and a BODY placeholder with index 0.
	LayoutPlaceholder *Placeholder `json:"layoutPlaceholder,omitempty"`

	// LayoutPlaceholderObjectId: The object ID of the placeholder on a
	// layout that will be applied
	// to a slide.
	LayoutPlaceholderObjectId string `json:"layoutPlaceholderObjectId,omitempty"`

	// ObjectId: A user-supplied object ID for the placeholder identified
	// above that to be
	// created onto a slide.
	//
	// If you specify an ID, it must be unique among all pages and page
	// elements
	// in the presentation. The ID must start with an alphanumeric character
	// or an
	// underscore (matches regex `[a-zA-Z0-9_]`); remaining characters
	// may include those as well as a hyphen or colon (matches
	// regex
	// `[a-zA-Z0-9_-:]`).
	// The length of the ID must not be less than 5 or greater than 50.
	//
	// If you don't specify an ID, a unique one is generated.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutPlaceholder")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutPlaceholder") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LayoutPlaceholderIdMapping) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutPlaceholderIdMapping
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutProperties: The properties of Page are only
// relevant for pages with page_type LAYOUT.
type LayoutProperties struct {
	// DisplayName: The human-readable name of the layout.
	DisplayName string `json:"displayName,omitempty"`

	// MasterObjectId: The object ID of the master that this layout is based
	// on.
	MasterObjectId string `json:"masterObjectId,omitempty"`

	// Name: The name of the layout.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DisplayName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LayoutProperties) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LayoutReference: Slide layout reference. This may reference
// either:
//
// - A predefined layout
// - One of the layouts in the presentation.
type LayoutReference struct {
	// LayoutId: Layout ID: the object ID of one of the layouts in the
	// presentation.
	LayoutId string `json:"layoutId,omitempty"`

	// PredefinedLayout: Predefined layout.
	//
	// Possible values:
	//   "PREDEFINED_LAYOUT_UNSPECIFIED" - Unspecified layout.
	//   "BLANK" - Blank layout, with no placeholders.
	//   "CAPTION_ONLY" - Layout with a caption at the bottom.
	//   "TITLE" - Layout with a title and a subtitle.
	//   "TITLE_AND_BODY" - Layout with a title and body.
	//   "TITLE_AND_TWO_COLUMNS" - Layout with a title and two columns.
	//   "TITLE_ONLY" - Layout with only a title.
	//   "SECTION_HEADER" - Layout with a section title.
	//   "SECTION_TITLE_AND_DESCRIPTION" - Layout with a title and subtitle
	// on one side and description on the other.
	//   "ONE_COLUMN_TEXT" - Layout with one title and one body, arranged in
	// a single column.
	//   "MAIN_POINT" - Layout with a main point.
	//   "BIG_NUMBER" - Layout with a big number heading.
	PredefinedLayout string `json:"predefinedLayout,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LayoutReference) MarshalJSON() ([]byte, error) {
	type NoMethod LayoutReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Line: A PageElement kind representing a
// non-connector line, straight connector, curved connector, or bent
// connector.
type Line struct {
	// LineCategory: The category of the line.
	//
	// It matches the `category` specified in CreateLineRequest, and can be
	// updated with
	// UpdateLineCategoryRequest.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// LineProperties: The properties of the line.
	LineProperties *LineProperties `json:"lineProperties,omitempty"`

	// LineType: The type of the line.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - An unspecified line type.
	//   "STRAIGHT_CONNECTOR_1" - Straight connector 1 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'straightConnector1'.
	//   "BENT_CONNECTOR_2" - Bent connector 2 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector2'.
	//   "BENT_CONNECTOR_3" - Bent connector 3 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector3'.
	//   "BENT_CONNECTOR_4" - Bent connector 4 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector4'.
	//   "BENT_CONNECTOR_5" - Bent connector 5 form. Corresponds to ECMA-376
	// ST_ShapeType
	// 'bentConnector5'.
	//   "CURVED_CONNECTOR_2" - Curved connector 2 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector2'.
	//   "CURVED_CONNECTOR_3" - Curved connector 3 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector3'.
	//   "CURVED_CONNECTOR_4" - Curved connector 4 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector4'.
	//   "CURVED_CONNECTOR_5" - Curved connector 5 form. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedConnector5'.
	//   "STRAIGHT_LINE" - Straight line. Corresponds to ECMA-376
	// ST_ShapeType 'line'. This line
	// type is not a connector.
	LineType string `json:"lineType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LineCategory") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LineCategory") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Line) MarshalJSON() ([]byte, error) {
	type NoMethod Line
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineConnection: The properties for one end of a Line
// connection.
type LineConnection struct {
	// ConnectedObjectId: The object ID of the connected page element.
	//
	// Some page elements, such as groups, tables, and lines
	// do not have connection sites and therefore cannot be connected to
	// a
	// connector line.
	ConnectedObjectId string `json:"connectedObjectId,omitempty"`

	// ConnectionSiteIndex: The index of the connection site on the
	// connected page element.
	//
	// In most cases, it corresponds to the predefined connection site index
	// from
	// the ECMA-376 standard. More information on those connection sites can
	// be
	// found in the description of the "cnx" attribute in section 20.1.9.9
	// and
	// Annex H. "Predefined DrawingML Shape and Text Geometries" of "Office
	// Open
	// XML File Formats-Fundamentals and Markup Language Reference", part 1
	// of
	// [ECMA-376 5th
	// edition]
	// (http://www.ecma-international.org/publications/standards/Ecm
	// a-376.htm).
	//
	// The position of each connection site can also be viewed from Slides
	// editor.
	ConnectionSiteIndex int64 `json:"connectionSiteIndex,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConnectedObjectId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ConnectedObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *LineConnection) MarshalJSON() ([]byte, error) {
	type NoMethod LineConnection
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineFill: The fill of the line.
type LineFill struct {
	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LineFill) MarshalJSON() ([]byte, error) {
	type NoMethod LineFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LineProperties: The properties of the Line.
//
// When unset, these fields default to values that match the appearance
// of
// new lines created in the Slides editor.
type LineProperties struct {
	// DashStyle: The dash style of the line.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// EndArrow: The style of the arrow at the end of the line.
	//
	// Possible values:
	//   "ARROW_STYLE_UNSPECIFIED" - An unspecified arrow style.
	//   "NONE" - No arrow.
	//   "STEALTH_ARROW" - Arrow with notched back. Corresponds to ECMA-376
	// ST_LineEndType value
	// 'stealth'.
	//   "FILL_ARROW" - Filled arrow. Corresponds to ECMA-376 ST_LineEndType
	// value 'triangle'.
	//   "FILL_CIRCLE" - Filled circle. Corresponds to ECMA-376
	// ST_LineEndType value 'oval'.
	//   "FILL_SQUARE" - Filled square.
	//   "FILL_DIAMOND" - Filled diamond. Corresponds to ECMA-376
	// ST_LineEndType value 'diamond'.
	//   "OPEN_ARROW" - Hollow arrow.
	//   "OPEN_CIRCLE" - Hollow circle.
	//   "OPEN_SQUARE" - Hollow square.
	//   "OPEN_DIAMOND" - Hollow diamond.
	EndArrow string `json:"endArrow,omitempty"`

	// EndConnection: The connection at the end of the line. If unset, there
	// is no connection.
	//
	// Only lines with a Type indicating it is
	// a "connector" can have an `end_connection`.
	EndConnection *LineConnection `json:"endConnection,omitempty"`

	// LineFill: The fill of the line. The default line fill matches the
	// defaults for new
	// lines created in the Slides editor.
	LineFill *LineFill `json:"lineFill,omitempty"`

	// Link: The hyperlink destination of the line. If unset, there is no
	// link.
	Link *Link `json:"link,omitempty"`

	// StartArrow: The style of the arrow at the beginning of the line.
	//
	// Possible values:
	//   "ARROW_STYLE_UNSPECIFIED" - An unspecified arrow style.
	//   "NONE" - No arrow.
	//   "STEALTH_ARROW" - Arrow with notched back. Corresponds to ECMA-376
	// ST_LineEndType value
	// 'stealth'.
	//   "FILL_ARROW" - Filled arrow. Corresponds to ECMA-376 ST_LineEndType
	// value 'triangle'.
	//   "FILL_CIRCLE" - Filled circle. Corresponds to ECMA-376
	// ST_LineEndType value 'oval'.
	//   "FILL_SQUARE" - Filled square.
	//   "FILL_DIAMOND" - Filled diamond. Corresponds to ECMA-376
	// ST_LineEndType value 'diamond'.
	//   "OPEN_ARROW" - Hollow arrow.
	//   "OPEN_CIRCLE" - Hollow circle.
	//   "OPEN_SQUARE" - Hollow square.
	//   "OPEN_DIAMOND" - Hollow diamond.
	StartArrow string `json:"startArrow,omitempty"`

	// StartConnection: The connection at the beginning of the line. If
	// unset, there is no
	// connection.
	//
	// Only lines with a Type indicating it is
	// a "connector" can have a `start_connection`.
	StartConnection *LineConnection `json:"startConnection,omitempty"`

	// Weight: The thickness of the line.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *LineProperties) MarshalJSON() ([]byte, error) {
	type NoMethod LineProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Link: A hypertext link.
type Link struct {
	// PageObjectId: If set, indicates this is a link to the specific page
	// in this
	// presentation with this ID. A page with this ID may not exist.
	PageObjectId string `json:"pageObjectId,omitempty"`

	// RelativeLink: If set, indicates this is a link to a slide in this
	// presentation,
	// addressed by its position.
	//
	// Possible values:
	//   "RELATIVE_SLIDE_LINK_UNSPECIFIED" - An unspecified relative slide
	// link.
	//   "NEXT_SLIDE" - A link to the next slide.
	//   "PREVIOUS_SLIDE" - A link to the previous slide.
	//   "FIRST_SLIDE" - A link to the first slide in the presentation.
	//   "LAST_SLIDE" - A link to the last slide in the presentation.
	RelativeLink string `json:"relativeLink,omitempty"`

	// SlideIndex: If set, indicates this is a link to the slide at this
	// zero-based index
	// in the presentation. There may not be a slide at this index.
	SlideIndex int64 `json:"slideIndex,omitempty"`

	// Url: If set, indicates this is a link to the external web page at
	// this URL.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Link) MarshalJSON() ([]byte, error) {
	type NoMethod Link
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// List: A List describes the look and feel of bullets belonging to
// paragraphs
// associated with a list. A paragraph that is part of a list has an
// implicit
// reference to that list's ID.
type List struct {
	// ListId: The ID of the list.
	ListId string `json:"listId,omitempty"`

	// NestingLevel: A map of nesting levels to the properties of bullets at
	// the associated
	// level. A list has at most nine levels of nesting, so the possible
	// values
	// for the keys of this map are 0 through 8, inclusive.
	NestingLevel map[string]NestingLevel `json:"nestingLevel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ListId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ListId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *List) MarshalJSON() ([]byte, error) {
	type NoMethod List
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MasterProperties: The properties of Page that are only
// relevant for pages with page_type MASTER.
type MasterProperties struct {
	// DisplayName: The human-readable name of the master.
	DisplayName string `json:"displayName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DisplayName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MasterProperties) MarshalJSON() ([]byte, error) {
	type NoMethod MasterProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// MergeTableCellsRequest: Merges cells in a Table.
type MergeTableCellsRequest struct {
	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableRange: The table range specifying which cells of the table to
	// merge.
	//
	// Any text in the cells being merged will be concatenated and stored in
	// the
	// upper-left ("head") cell of the range. If the range is
	// non-rectangular
	// (which can occur in some cases where the range covers cells that
	// are
	// already merged), a 400 bad request error is returned.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *MergeTableCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod MergeTableCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NestingLevel: Contains properties describing the look and feel of a
// list bullet at a given
// level of nesting.
type NestingLevel struct {
	// BulletStyle: The style of a bullet at this level of nesting.
	BulletStyle *TextStyle `json:"bulletStyle,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BulletStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BulletStyle") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NestingLevel) MarshalJSON() ([]byte, error) {
	type NoMethod NestingLevel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// NotesProperties: The properties of Page that are only
// relevant for pages with page_type NOTES.
type NotesProperties struct {
	// SpeakerNotesObjectId: The object ID of the shape on this notes page
	// that contains the speaker
	// notes for the corresponding slide.
	// The actual shape may not always exist on the notes page. Inserting
	// text
	// using this object ID will automatically create the shape. In this
	// case, the
	// actual shape may have different object ID. The `GetPresentation`
	// or
	// `GetPage` action will always return the latest object ID.
	SpeakerNotesObjectId string `json:"speakerNotesObjectId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "SpeakerNotesObjectId") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SpeakerNotesObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NotesProperties) MarshalJSON() ([]byte, error) {
	type NoMethod NotesProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OpaqueColor: A themeable solid color value.
type OpaqueColor struct {
	// RgbColor: An opaque RGB color.
	RgbColor *RgbColor `json:"rgbColor,omitempty"`

	// ThemeColor: An opaque theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color. This
	// value should not be used.
	//   "DARK1" - Represents the first dark color.
	//   "LIGHT1" - Represents the first light color.
	//   "DARK2" - Represents the second dark color.
	//   "LIGHT2" - Represents the second light color.
	//   "ACCENT1" - Represents the first accent color.
	//   "ACCENT2" - Represents the second accent color.
	//   "ACCENT3" - Represents the third accent color.
	//   "ACCENT4" - Represents the fourth accent color.
	//   "ACCENT5" - Represents the fifth accent color.
	//   "ACCENT6" - Represents the sixth accent color.
	//   "HYPERLINK" - Represents the color to use for hyperlinks.
	//   "FOLLOWED_HYPERLINK" - Represents the color to use for visited
	// hyperlinks.
	//   "TEXT1" - Represents the first text color.
	//   "BACKGROUND1" - Represents the first background color.
	//   "TEXT2" - Represents the second text color.
	//   "BACKGROUND2" - Represents the second background color.
	ThemeColor string `json:"themeColor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RgbColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RgbColor") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OpaqueColor) MarshalJSON() ([]byte, error) {
	type NoMethod OpaqueColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OptionalColor: A color that can either be fully opaque or fully
// transparent.
type OptionalColor struct {
	// OpaqueColor: If set, this will be used as an opaque color. If unset,
	// this represents
	// a transparent color.
	OpaqueColor *OpaqueColor `json:"opaqueColor,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OpaqueColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OpaqueColor") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OptionalColor) MarshalJSON() ([]byte, error) {
	type NoMethod OptionalColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Outline: The outline of a PageElement.
//
// If these fields are unset, they may be inherited from a parent
// placeholder
// if it exists. If there is no parent, the fields will default to the
// value
// used for new page elements created in the Slides editor, which may
// depend on
// the page element kind.
type Outline struct {
	// DashStyle: The dash style of the outline.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// OutlineFill: The fill of the outline.
	OutlineFill *OutlineFill `json:"outlineFill,omitempty"`

	// PropertyState: The outline property state.
	//
	// Updating the outline on a page element will implicitly update this
	// field
	// to `RENDERED`, unless another value is specified in the same request.
	// To
	// have no outline on a page element, set this field to `NOT_RENDERED`.
	// In
	// this case, any other outline fields set in the same request will
	// be
	// ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// Weight: The thickness of the outline.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Outline) MarshalJSON() ([]byte, error) {
	type NoMethod Outline
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// OutlineFill: The fill of the outline.
type OutlineFill struct {
	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *OutlineFill) MarshalJSON() ([]byte, error) {
	type NoMethod OutlineFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Page: A page in a presentation.
type Page struct {
	// LayoutProperties: Layout specific properties. Only set if page_type =
	// LAYOUT.
	LayoutProperties *LayoutProperties `json:"layoutProperties,omitempty"`

	// MasterProperties: Master specific properties. Only set if page_type =
	// MASTER.
	MasterProperties *MasterProperties `json:"masterProperties,omitempty"`

	// NotesProperties: Notes specific properties. Only set if page_type =
	// NOTES.
	NotesProperties *NotesProperties `json:"notesProperties,omitempty"`

	// ObjectId: The object ID for this page. Object IDs used by
	// Page and
	// PageElement share the same namespace.
	ObjectId string `json:"objectId,omitempty"`

	// PageElements: The page elements rendered on the page.
	PageElements []*PageElement `json:"pageElements,omitempty"`

	// PageProperties: The properties of the page.
	PageProperties *PageProperties `json:"pageProperties,omitempty"`

	// PageType: The type of the page.
	//
	// Possible values:
	//   "SLIDE" - A slide page.
	//   "MASTER" - A master slide page.
	//   "LAYOUT" - A layout page.
	//   "NOTES" - A notes page.
	//   "NOTES_MASTER" - A notes master page.
	PageType string `json:"pageType,omitempty"`

	// RevisionId: The revision ID of the presentation containing this page.
	// Can be used in
	// update requests to assert that the presentation revision hasn't
	// changed
	// since the last read operation. Only populated if the user has edit
	// access
	// to the presentation.
	//
	// The format of the revision ID may change over time, so it should be
	// treated
	// opaquely. A returned revision ID is only guaranteed to be valid for
	// 24
	// hours after it has been returned and cannot be shared across users.
	// If the
	// revision ID is unchanged between calls, then the presentation has
	// not
	// changed. Conversely, a changed ID (for the same presentation and
	// user)
	// usually means the presentation has been updated; however, a changed
	// ID can
	// also be due to internal factors such as ID format changes.
	RevisionId string `json:"revisionId,omitempty"`

	// SlideProperties: Slide specific properties. Only set if page_type =
	// SLIDE.
	SlideProperties *SlideProperties `json:"slideProperties,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "LayoutProperties") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *Page) MarshalJSON() ([]byte, error) {
	type NoMethod Page
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageBackgroundFill: The page background fill.
type PageBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a page will implicitly update this field
	// to
	// `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a page, set this field to `NOT_RENDERED`. In this
	// case,
	// any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// StretchedPictureFill: Stretched picture fill.
	StretchedPictureFill *StretchedPictureFill `json:"stretchedPictureFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod PageBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageElement: A visual element rendered on a page.
type PageElement struct {
	// Description: The description of the page element. Combined with title
	// to display alt
	// text.
	Description string `json:"description,omitempty"`

	// ElementGroup: A collection of page elements joined as a single unit.
	ElementGroup *Group `json:"elementGroup,omitempty"`

	// Image: An image page element.
	Image *Image `json:"image,omitempty"`

	// Line: A line page element.
	Line *Line `json:"line,omitempty"`

	// ObjectId: The object ID for this page element. Object IDs used
	// by
	// google.apps.slides.v1.Page and
	// google.apps.slides.v1.PageElement share the same namespace.
	ObjectId string `json:"objectId,omitempty"`

	// Shape: A generic shape.
	Shape *Shape `json:"shape,omitempty"`

	// SheetsChart: A linked chart embedded from Google Sheets. Unlinked
	// charts are
	// represented as images.
	SheetsChart *SheetsChart `json:"sheetsChart,omitempty"`

	// Size: The size of the page element.
	Size *Size `json:"size,omitempty"`

	// Table: A table page element.
	Table *Table `json:"table,omitempty"`

	// Title: The title of the page element. Combined with description to
	// display alt
	// text.
	Title string `json:"title,omitempty"`

	// Transform: The transform of the page element.
	//
	// The visual appearance of the page element is determined by its
	// absolute
	// transform. To compute the absolute transform, preconcatenate a
	// page
	// element's transform with the transforms of all of its parent groups.
	// If the
	// page element is not in a group, its absolute transform is the same as
	// the
	// value in this field.
	//
	// The initial transform for the newly created Group is always the
	// identity transform.
	Transform *AffineTransform `json:"transform,omitempty"`

	// Video: A video page element.
	Video *Video `json:"video,omitempty"`

	// WordArt: A word art page element.
	WordArt *WordArt `json:"wordArt,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageElement) MarshalJSON() ([]byte, error) {
	type NoMethod PageElement
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageElementProperties: Common properties for a page element.
//
// Note: When you initially create a
// PageElement, the API may modify
// the values of both `size` and `transform`, but the
// visual size will be unchanged.
type PageElementProperties struct {
	// PageObjectId: The object ID of the page where the element is located.
	PageObjectId string `json:"pageObjectId,omitempty"`

	// Size: The size of the element.
	Size *Size `json:"size,omitempty"`

	// Transform: The transform for the element.
	Transform *AffineTransform `json:"transform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageElementProperties) MarshalJSON() ([]byte, error) {
	type NoMethod PageElementProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// PageProperties: The properties of the Page.
//
// The page will inherit properties from the parent page. Depending on
// the page
// type the hierarchy is defined in either
// SlideProperties or
// LayoutProperties.
type PageProperties struct {
	// ColorScheme: The color scheme of the page. If unset, the color scheme
	// is inherited from
	// a parent page. If the page has no parent, the color scheme uses a
	// default
	// Slides color scheme, matching the defaults in the Slides
	// editor.
	//
	// Only the concrete colors of the first 12 ThemeColorTypes are
	// editable. In addition, only
	// the color scheme on `Master` pages can be updated. To update the
	// field, a
	// color scheme containing mappings from all the first 12
	// ThemeColorTypes to
	// their concrete colors must be provided. Colors for the
	// remaining
	// ThemeColorTypes will be ignored.
	ColorScheme *ColorScheme `json:"colorScheme,omitempty"`

	// PageBackgroundFill: The background fill of the page. If unset, the
	// background fill is inherited
	// from a parent page if it exists. If the page has no parent, then
	// the
	// background fill defaults to the corresponding fill in the Slides
	// editor.
	PageBackgroundFill *PageBackgroundFill `json:"pageBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColorScheme") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColorScheme") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *PageProperties) MarshalJSON() ([]byte, error) {
	type NoMethod PageProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParagraphMarker: A TextElement kind that represents the beginning of
// a new paragraph.
type ParagraphMarker struct {
	// Bullet: The bullet for this paragraph. If not present, the paragraph
	// does not
	// belong to a list.
	Bullet *Bullet `json:"bullet,omitempty"`

	// Style: The paragraph's style
	Style *ParagraphStyle `json:"style,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bullet") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bullet") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ParagraphMarker) MarshalJSON() ([]byte, error) {
	type NoMethod ParagraphMarker
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ParagraphStyle: Styles that apply to a whole paragraph.
//
// If this text is contained in a shape with a parent placeholder, then
// these paragraph styles may be
// inherited from the parent. Which paragraph styles are inherited
// depend on the
// nesting level of lists:
//
// * A paragraph not in a list will inherit its paragraph style from
// the
//   paragraph at the 0 nesting level of the list inside the parent
// placeholder.
// * A paragraph in a list will inherit its paragraph style from the
// paragraph
//   at its corresponding nesting level of the list inside the parent
//   placeholder.
//
// Inherited paragraph styles are represented as unset fields in this
// message.
type ParagraphStyle struct {
	// Alignment: The text alignment for this paragraph.
	//
	// Possible values:
	//   "ALIGNMENT_UNSPECIFIED" - The paragraph alignment is inherited from
	// the parent.
	//   "START" - The paragraph is aligned to the start of the line.
	// Left-aligned for
	// LTR text, right-aligned otherwise.
	//   "CENTER" - The paragraph is centered.
	//   "END" - The paragraph is aligned to the end of the line.
	// Right-aligned for
	// LTR text, left-aligned otherwise.
	//   "JUSTIFIED" - The paragraph is justified.
	Alignment string `json:"alignment,omitempty"`

	// Direction: The text direction of this paragraph. If unset, the value
	// defaults to
	// LEFT_TO_RIGHT since
	// text direction is not inherited.
	//
	// Possible values:
	//   "TEXT_DIRECTION_UNSPECIFIED" - The text direction is inherited from
	// the parent.
	//   "LEFT_TO_RIGHT" - The text goes from left to right.
	//   "RIGHT_TO_LEFT" - The text goes from right to left.
	Direction string `json:"direction,omitempty"`

	// IndentEnd: The amount indentation for the paragraph on the side that
	// corresponds to
	// the end of the text, based on the current text direction. If unset,
	// the
	// value is inherited from the parent.
	IndentEnd *Dimension `json:"indentEnd,omitempty"`

	// IndentFirstLine: The amount of indentation for the start of the first
	// line of the paragraph.
	// If unset, the value is inherited from the parent.
	IndentFirstLine *Dimension `json:"indentFirstLine,omitempty"`

	// IndentStart: The amount indentation for the paragraph on the side
	// that corresponds to
	// the start of the text, based on the current text direction. If unset,
	// the
	// value is inherited from the parent.
	IndentStart *Dimension `json:"indentStart,omitempty"`

	// LineSpacing: The amount of space between lines, as a percentage of
	// normal, where normal
	// is represented as 100.0. If unset, the value is inherited from the
	// parent.
	LineSpacing float64 `json:"lineSpacing,omitempty"`

	// SpaceAbove: The amount of extra space above the paragraph. If unset,
	// the value is
	// inherited from the parent.
	SpaceAbove *Dimension `json:"spaceAbove,omitempty"`

	// SpaceBelow: The amount of extra space below the paragraph. If unset,
	// the value is
	// inherited from the parent.
	SpaceBelow *Dimension `json:"spaceBelow,omitempty"`

	// SpacingMode: The spacing mode for the paragraph.
	//
	// Possible values:
	//   "SPACING_MODE_UNSPECIFIED" - The spacing mode is inherited from the
	// parent.
	//   "NEVER_COLLAPSE" - Paragraph spacing is always rendered.
	//   "COLLAPSE_LISTS" - Paragraph spacing is skipped between list
	// elements.
	SpacingMode string `json:"spacingMode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alignment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ParagraphStyle) MarshalJSON() ([]byte, error) {
	type NoMethod ParagraphStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *ParagraphStyle) UnmarshalJSON(data []byte) error {
	type NoMethod ParagraphStyle
	var s1 struct {
		LineSpacing gensupport.JSONFloat64 `json:"lineSpacing"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.LineSpacing = float64(s1.LineSpacing)
	return nil
}

// Placeholder: The placeholder information that uniquely identifies a
// placeholder shape.
type Placeholder struct {
	// Index: The index of the placeholder. If the same placeholder types
	// are present in
	// the same page, they would have different index values.
	Index int64 `json:"index,omitempty"`

	// ParentObjectId: The object ID of this shape's parent placeholder.
	// If unset, the parent placeholder shape does not exist, so the shape
	// does
	// not inherit properties from any other shape.
	ParentObjectId string `json:"parentObjectId,omitempty"`

	// Type: The type of the placeholder.
	//
	// Possible values:
	//   "NONE" - Default value, signifies it is not a placeholder.
	//   "BODY" - Body text.
	//   "CHART" - Chart or graph.
	//   "CLIP_ART" - Clip art image.
	//   "CENTERED_TITLE" - Title centered.
	//   "DIAGRAM" - Diagram.
	//   "DATE_AND_TIME" - Date and time.
	//   "FOOTER" - Footer text.
	//   "HEADER" - Header text.
	//   "MEDIA" - Multimedia.
	//   "OBJECT" - Any content type.
	//   "PICTURE" - Picture.
	//   "SLIDE_NUMBER" - Number of a slide.
	//   "SUBTITLE" - Subtitle.
	//   "TABLE" - Table.
	//   "TITLE" - Slide title.
	//   "SLIDE_IMAGE" - Slide image.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Index") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Index") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Placeholder) MarshalJSON() ([]byte, error) {
	type NoMethod Placeholder
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Presentation: A Google Slides presentation.
type Presentation struct {
	// Layouts: The layouts in the presentation. A layout is a template that
	// determines
	// how content is arranged and styled on the slides that inherit from
	// that
	// layout.
	Layouts []*Page `json:"layouts,omitempty"`

	// Locale: The locale of the presentation, as an IETF BCP 47 language
	// tag.
	Locale string `json:"locale,omitempty"`

	// Masters: The slide masters in the presentation. A slide master
	// contains all common
	// page elements and the common properties for a set of layouts. They
	// serve
	// three purposes:
	//
	// - Placeholder shapes on a master contain the default text styles and
	// shape
	//   properties of all placeholder shapes on pages that use that
	// master.
	// - The master page properties define the common page properties
	// inherited by
	//   its layouts.
	// - Any other shapes on the master slide will appear on all slides
	// using that
	//   master, regardless of their layout.
	Masters []*Page `json:"masters,omitempty"`

	// NotesMaster: The notes master in the presentation. It serves three
	// purposes:
	//
	// - Placeholder shapes on a notes master contain the default text
	// styles and
	//   shape properties of all placeholder shapes on notes pages.
	// Specifically,
	//   a `SLIDE_IMAGE` placeholder shape contains the slide thumbnail, and
	// a
	//   `BODY` placeholder shape contains the speaker notes.
	// - The notes master page properties define the common page properties
	//   inherited by all notes pages.
	// - Any other shapes on the notes master will appear on all notes
	// pages.
	//
	// The notes master is read-only.
	NotesMaster *Page `json:"notesMaster,omitempty"`

	// PageSize: The size of pages in the presentation.
	PageSize *Size `json:"pageSize,omitempty"`

	// PresentationId: The ID of the presentation.
	PresentationId string `json:"presentationId,omitempty"`

	// RevisionId: The revision ID of the presentation. Can be used in
	// update requests
	// to assert that the presentation revision hasn't changed since the
	// last
	// read operation. Only populated if the user has edit access to
	// the
	// presentation.
	//
	// The format of the revision ID may change over time, so it should be
	// treated
	// opaquely. A returned revision ID is only guaranteed to be valid for
	// 24
	// hours after it has been returned and cannot be shared across users.
	// If the
	// revision ID is unchanged between calls, then the presentation has
	// not
	// changed. Conversely, a changed ID (for the same presentation and
	// user)
	// usually means the presentation has been updated; however, a changed
	// ID can
	// also be due to internal factors such as ID format changes.
	RevisionId string `json:"revisionId,omitempty"`

	// Slides: The slides in the presentation.
	// A slide inherits properties from a slide layout.
	Slides []*Page `json:"slides,omitempty"`

	// Title: The title of the presentation.
	Title string `json:"title,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Layouts") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Layouts") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Presentation) MarshalJSON() ([]byte, error) {
	type NoMethod Presentation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Range: Specifies a contiguous range of an indexed collection, such as
// characters in
// text.
type Range struct {
	// EndIndex: The optional zero-based index of the end of the
	// collection.
	// Required for `FIXED_RANGE` ranges.
	EndIndex int64 `json:"endIndex,omitempty"`

	// StartIndex: The optional zero-based index of the beginning of the
	// collection.
	// Required for `FIXED_RANGE` and `FROM_START_INDEX` ranges.
	StartIndex int64 `json:"startIndex,omitempty"`

	// Type: The type of range.
	//
	// Possible values:
	//   "RANGE_TYPE_UNSPECIFIED" - Unspecified range type. This value must
	// not be used.
	//   "FIXED_RANGE" - A fixed range. Both the `start_index`
	// and
	// `end_index` must be specified.
	//   "FROM_START_INDEX" - Starts the range at `start_index` and
	// continues until the
	// end of the collection. The `end_index` must not be specified.
	//   "ALL" - Sets the range to be the whole length of the collection.
	// Both the
	// `start_index` and the `end_index` must not be
	// specified.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndIndex") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Range) MarshalJSON() ([]byte, error) {
	type NoMethod Range
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Recolor: A recolor effect applied on an image.
type Recolor struct {
	// Name: The name of the recolor effect.
	//
	// The name is determined from the `recolor_stops` by matching the
	// gradient
	// against the colors in the page's current color scheme. This property
	// is
	// read-only.
	//
	// Possible values:
	//   "NONE" - No recolor effect. The default value.
	//   "LIGHT1" - A recolor effect that lightens the image using the
	// page's first available
	// color from its color scheme.
	//   "LIGHT2" - A recolor effect that lightens the image using the
	// page's second
	// available color from its color scheme.
	//   "LIGHT3" - A recolor effect that lightens the image using the
	// page's third available
	// color from its color scheme.
	//   "LIGHT4" - A recolor effect that lightens the image using the
	// page's forth available
	// color from its color scheme.
	//   "LIGHT5" - A recolor effect that lightens the image using the
	// page's fifth available
	// color from its color scheme.
	//   "LIGHT6" - A recolor effect that lightens the image using the
	// page's sixth available
	// color from its color scheme.
	//   "LIGHT7" - A recolor effect that lightens the image using the
	// page's seventh
	// available color from its color scheme.
	//   "LIGHT8" - A recolor effect that lightens the image using the
	// page's eighth
	// available color from its color scheme.
	//   "LIGHT9" - A recolor effect that lightens the image using the
	// page's ninth available
	// color from its color scheme.
	//   "LIGHT10" - A recolor effect that lightens the image using the
	// page's tenth available
	// color from its color scheme.
	//   "DARK1" - A recolor effect that darkens the image using the page's
	// first available
	// color from its color scheme.
	//   "DARK2" - A recolor effect that darkens the image using the page's
	// second available
	// color from its color scheme.
	//   "DARK3" - A recolor effect that darkens the image using the page's
	// third available
	// color from its color scheme.
	//   "DARK4" - A recolor effect that darkens the image using the page's
	// fourth available
	// color from its color scheme.
	//   "DARK5" - A recolor effect that darkens the image using the page's
	// fifth available
	// color from its color scheme.
	//   "DARK6" - A recolor effect that darkens the image using the page's
	// sixth available
	// color from its color scheme.
	//   "DARK7" - A recolor effect that darkens the image using the page's
	// seventh
	// available color from its color scheme.
	//   "DARK8" - A recolor effect that darkens the image using the page's
	// eighth available
	// color from its color scheme.
	//   "DARK9" - A recolor effect that darkens the image using the page's
	// ninth available
	// color from its color scheme.
	//   "DARK10" - A recolor effect that darkens the image using the page's
	// tenth available
	// color from its color scheme.
	//   "GRAYSCALE" - A recolor effect that recolors the image to
	// grayscale.
	//   "NEGATIVE" - A recolor effect that recolors the image to negative
	// grayscale.
	//   "SEPIA" - A recolor effect that recolors the image using the sepia
	// color.
	//   "CUSTOM" - Custom recolor effect. Refer to `recolor_stops` for the
	// concrete
	// gradient.
	Name string `json:"name,omitempty"`

	// RecolorStops: The recolor effect is represented by a gradient, which
	// is a list of color
	// stops.
	//
	// The colors in the gradient will replace the corresponding colors
	// at
	// the same position in the color palette and apply to the image.
	// This
	// property is read-only.
	RecolorStops []*ColorStop `json:"recolorStops,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Recolor) MarshalJSON() ([]byte, error) {
	type NoMethod Recolor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RefreshSheetsChartRequest: Refreshes an embedded Google Sheets chart
// by replacing it with the latest
// version of the chart from Google Sheets.
//
// NOTE: Refreshing charts requires  at least one of the
// spreadsheets.readonly,
// spreadsheets, drive.readonly, or drive OAuth scopes.
type RefreshSheetsChartRequest struct {
	// ObjectId: The object ID of the chart to refresh.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RefreshSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RefreshSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithImageRequest: Replaces all shapes that match the
// given criteria with the provided image.
//
// The images replacing the shapes are rectangular after being inserted
// into
// the presentation and do not take on the forms of the shapes.
type ReplaceAllShapesWithImageRequest struct {
	// ContainsText: If set, this request will replace all of the shapes
	// that contain the
	// given text.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// ImageReplaceMethod: The image replace method.
	//
	// If you specify both a `replace_method` and an `image_replace_method`,
	// the
	// `image_replace_method` takes precedence.
	//
	// If you do not specify a value for `image_replace_method`, but specify
	// a
	// value for `replace_method`, then the specified `replace_method` value
	// is
	// used.
	//
	// If you do not specify either, then CENTER_INSIDE is used.
	//
	// Possible values:
	//   "IMAGE_REPLACE_METHOD_UNSPECIFIED" - Unspecified image replace
	// method. This value must not be used.
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ImageReplaceMethod string `json:"imageReplaceMethod,omitempty"`

	// ImageUrl: The image URL.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	ImageUrl string `json:"imageUrl,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes page or a
	// notes master, or if a
	// page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// ReplaceMethod: The replace method.
	//
	// <b>Deprecated</b>: use `image_replace_method` instead.
	//
	// If you specify both a `replace_method` and an `image_replace_method`,
	// the
	// `image_replace_method` takes precedence.
	//
	// Possible values:
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ReplaceMethod string `json:"replaceMethod,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContainsText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainsText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithImageResponse: The result of replacing shapes
// with an image.
type ReplaceAllShapesWithImageResponse struct {
	// OccurrencesChanged: The number of shapes replaced with images.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithImageResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithImageResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithSheetsChartRequest: Replaces all shapes that
// match the given criteria with the provided Google
// Sheets chart. The chart will be scaled and centered to fit within the
// bounds
// of the original shape.
//
// NOTE: Replacing shapes with a chart requires at least one of
// the
// spreadsheets.readonly, spreadsheets, drive.readonly, or drive OAuth
// scopes.
type ReplaceAllShapesWithSheetsChartRequest struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet.
	ChartId int64 `json:"chartId,omitempty"`

	// ContainsText: The criteria that the shapes must match in order to be
	// replaced. The
	// request will replace all of the shapes that contain the given text.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// LinkingMode: The mode with which the chart is linked to the source
	// spreadsheet. When
	// not specified, the chart will be an image that is not linked.
	//
	// Possible values:
	//   "NOT_LINKED_IMAGE" - The chart is not associated with the source
	// spreadsheet and cannot be
	// updated. A chart that is not linked will be inserted as an image.
	//   "LINKED" - Linking the chart allows it to be updated, and other
	// collaborators will
	// see a link to the spreadsheet.
	LinkingMode string `json:"linkingMode,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes page or a
	// notes master, or if a
	// page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithSheetsChartRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithSheetsChartRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllShapesWithSheetsChartResponse: The result of replacing
// shapes with a Google Sheets chart.
type ReplaceAllShapesWithSheetsChartResponse struct {
	// OccurrencesChanged: The number of shapes replaced with charts.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllShapesWithSheetsChartResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllShapesWithSheetsChartResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllTextRequest: Replaces all instances of text matching a
// criteria with replace text.
type ReplaceAllTextRequest struct {
	// ContainsText: Finds text in a shape matching this substring.
	ContainsText *SubstringMatchCriteria `json:"containsText,omitempty"`

	// PageObjectIds: If non-empty, limits the matches to page elements only
	// on the given pages.
	//
	// Returns a 400 bad request error if given the page object ID of
	// a
	// notes master,
	// or if a page with that object ID doesn't exist in the presentation.
	PageObjectIds []string `json:"pageObjectIds,omitempty"`

	// ReplaceText: The text that will replace the matched text.
	ReplaceText string `json:"replaceText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContainsText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContainsText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceAllTextResponse: The result of replacing text.
type ReplaceAllTextResponse struct {
	// OccurrencesChanged: The number of occurrences changed by replacing
	// all text.
	OccurrencesChanged int64 `json:"occurrencesChanged,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OccurrencesChanged")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "OccurrencesChanged") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceAllTextResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceAllTextResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ReplaceImageRequest: Replaces an existing image with a new
// image.
//
// Replacing an image removes some image effects from the existing
// image.
type ReplaceImageRequest struct {
	// ImageObjectId: The ID of the existing image that will be replaced.
	ImageObjectId string `json:"imageObjectId,omitempty"`

	// ImageReplaceMethod: The replacement method.
	//
	// Possible values:
	//   "IMAGE_REPLACE_METHOD_UNSPECIFIED" - Unspecified image replace
	// method. This value must not be used.
	//   "CENTER_INSIDE" - Scales and centers the image to fit within the
	// bounds of the original
	// shape and maintains the image's aspect ratio. The rendered size of
	// the
	// image may be smaller than the size of the shape. This is the
	// default
	// method when one is not specified.
	//   "CENTER_CROP" - Scales and centers the image to fill the bounds of
	// the original shape.
	// The image may be cropped in order to fill the shape. The rendered
	// size of
	// the image will be the same as that of the original shape.
	ImageReplaceMethod string `json:"imageReplaceMethod,omitempty"`

	// Url: The image URL.
	//
	// The image is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Images must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length. The URL itself is
	// saved
	// with the image, and exposed via the Image.source_url field.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ImageObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ImageObjectId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ReplaceImageRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ReplaceImageRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Request: A single kind of update to apply to a presentation.
type Request struct {
	// CreateImage: Creates an image.
	CreateImage *CreateImageRequest `json:"createImage,omitempty"`

	// CreateLine: Creates a line.
	CreateLine *CreateLineRequest `json:"createLine,omitempty"`

	// CreateParagraphBullets: Creates bullets for paragraphs.
	CreateParagraphBullets *CreateParagraphBulletsRequest `json:"createParagraphBullets,omitempty"`

	// CreateShape: Creates a new shape.
	CreateShape *CreateShapeRequest `json:"createShape,omitempty"`

	// CreateSheetsChart: Creates an embedded Google Sheets chart.
	CreateSheetsChart *CreateSheetsChartRequest `json:"createSheetsChart,omitempty"`

	// CreateSlide: Creates a new slide.
	CreateSlide *CreateSlideRequest `json:"createSlide,omitempty"`

	// CreateTable: Creates a new table.
	CreateTable *CreateTableRequest `json:"createTable,omitempty"`

	// CreateVideo: Creates a video.
	CreateVideo *CreateVideoRequest `json:"createVideo,omitempty"`

	// DeleteObject: Deletes a page or page element from the presentation.
	DeleteObject *DeleteObjectRequest `json:"deleteObject,omitempty"`

	// DeleteParagraphBullets: Deletes bullets from paragraphs.
	DeleteParagraphBullets *DeleteParagraphBulletsRequest `json:"deleteParagraphBullets,omitempty"`

	// DeleteTableColumn: Deletes a column from a table.
	DeleteTableColumn *DeleteTableColumnRequest `json:"deleteTableColumn,omitempty"`

	// DeleteTableRow: Deletes a row from a table.
	DeleteTableRow *DeleteTableRowRequest `json:"deleteTableRow,omitempty"`

	// DeleteText: Deletes text from a shape or a table cell.
	DeleteText *DeleteTextRequest `json:"deleteText,omitempty"`

	// DuplicateObject: Duplicates a slide or page element.
	DuplicateObject *DuplicateObjectRequest `json:"duplicateObject,omitempty"`

	// GroupObjects: Groups objects, such as page elements.
	GroupObjects *GroupObjectsRequest `json:"groupObjects,omitempty"`

	// InsertTableColumns: Inserts columns into a table.
	InsertTableColumns *InsertTableColumnsRequest `json:"insertTableColumns,omitempty"`

	// InsertTableRows: Inserts rows into a table.
	InsertTableRows *InsertTableRowsRequest `json:"insertTableRows,omitempty"`

	// InsertText: Inserts text into a shape or table cell.
	InsertText *InsertTextRequest `json:"insertText,omitempty"`

	// MergeTableCells: Merges cells in a Table.
	MergeTableCells *MergeTableCellsRequest `json:"mergeTableCells,omitempty"`

	// RefreshSheetsChart: Refreshes a Google Sheets chart.
	RefreshSheetsChart *RefreshSheetsChartRequest `json:"refreshSheetsChart,omitempty"`

	// ReplaceAllShapesWithImage: Replaces all shapes matching some criteria
	// with an image.
	ReplaceAllShapesWithImage *ReplaceAllShapesWithImageRequest `json:"replaceAllShapesWithImage,omitempty"`

	// ReplaceAllShapesWithSheetsChart: Replaces all shapes matching some
	// criteria with a Google Sheets chart.
	ReplaceAllShapesWithSheetsChart *ReplaceAllShapesWithSheetsChartRequest `json:"replaceAllShapesWithSheetsChart,omitempty"`

	// ReplaceAllText: Replaces all instances of specified text.
	ReplaceAllText *ReplaceAllTextRequest `json:"replaceAllText,omitempty"`

	// ReplaceImage: Replaces an existing image with a new image.
	ReplaceImage *ReplaceImageRequest `json:"replaceImage,omitempty"`

	// RerouteLine: Reroutes a line such that it's connected
	// at the two closest connection sites on the connected page elements.
	RerouteLine *RerouteLineRequest `json:"rerouteLine,omitempty"`

	// UngroupObjects: Ungroups objects, such as groups.
	UngroupObjects *UngroupObjectsRequest `json:"ungroupObjects,omitempty"`

	// UnmergeTableCells: Unmerges cells in a Table.
	UnmergeTableCells *UnmergeTableCellsRequest `json:"unmergeTableCells,omitempty"`

	// UpdateImageProperties: Updates the properties of an Image.
	UpdateImageProperties *UpdateImagePropertiesRequest `json:"updateImageProperties,omitempty"`

	// UpdateLineCategory: Updates the category of a line.
	UpdateLineCategory *UpdateLineCategoryRequest `json:"updateLineCategory,omitempty"`

	// UpdateLineProperties: Updates the properties of a Line.
	UpdateLineProperties *UpdateLinePropertiesRequest `json:"updateLineProperties,omitempty"`

	// UpdatePageElementAltText: Updates the alt text title and/or
	// description of a
	// page element.
	UpdatePageElementAltText *UpdatePageElementAltTextRequest `json:"updatePageElementAltText,omitempty"`

	// UpdatePageElementTransform: Updates the transform of a page element.
	UpdatePageElementTransform *UpdatePageElementTransformRequest `json:"updatePageElementTransform,omitempty"`

	// UpdatePageElementsZOrder: Updates the Z-order of page elements.
	UpdatePageElementsZOrder *UpdatePageElementsZOrderRequest `json:"updatePageElementsZOrder,omitempty"`

	// UpdatePageProperties: Updates the properties of a Page.
	UpdatePageProperties *UpdatePagePropertiesRequest `json:"updatePageProperties,omitempty"`

	// UpdateParagraphStyle: Updates the styling of paragraphs within a
	// Shape or Table.
	UpdateParagraphStyle *UpdateParagraphStyleRequest `json:"updateParagraphStyle,omitempty"`

	// UpdateShapeProperties: Updates the properties of a Shape.
	UpdateShapeProperties *UpdateShapePropertiesRequest `json:"updateShapeProperties,omitempty"`

	// UpdateSlidesPosition: Updates the position of a set of slides in the
	// presentation.
	UpdateSlidesPosition *UpdateSlidesPositionRequest `json:"updateSlidesPosition,omitempty"`

	// UpdateTableBorderProperties: Updates the properties of the table
	// borders in a Table.
	UpdateTableBorderProperties *UpdateTableBorderPropertiesRequest `json:"updateTableBorderProperties,omitempty"`

	// UpdateTableCellProperties: Updates the properties of a TableCell.
	UpdateTableCellProperties *UpdateTableCellPropertiesRequest `json:"updateTableCellProperties,omitempty"`

	// UpdateTableColumnProperties: Updates the properties of a
	// Table
	// column.
	UpdateTableColumnProperties *UpdateTableColumnPropertiesRequest `json:"updateTableColumnProperties,omitempty"`

	// UpdateTableRowProperties: Updates the properties of a Table row.
	UpdateTableRowProperties *UpdateTableRowPropertiesRequest `json:"updateTableRowProperties,omitempty"`

	// UpdateTextStyle: Updates the styling of text within a Shape or Table.
	UpdateTextStyle *UpdateTextStyleRequest `json:"updateTextStyle,omitempty"`

	// UpdateVideoProperties: Updates the properties of a Video.
	UpdateVideoProperties *UpdateVideoPropertiesRequest `json:"updateVideoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateImage") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateImage") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Request) MarshalJSON() ([]byte, error) {
	type NoMethod Request
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RerouteLineRequest: Reroutes a line such that it's connected at
// the
// two closest connection sites on the connected page elements.
type RerouteLineRequest struct {
	// ObjectId: The object ID of the line to reroute.
	//
	// Only a line with a category
	// indicating it is a "connector" can be rerouted. The start and
	// end
	// connections of the line must be on different page elements.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RerouteLineRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RerouteLineRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Response: A single response from an update.
type Response struct {
	// CreateImage: The result of creating an image.
	CreateImage *CreateImageResponse `json:"createImage,omitempty"`

	// CreateLine: The result of creating a line.
	CreateLine *CreateLineResponse `json:"createLine,omitempty"`

	// CreateShape: The result of creating a shape.
	CreateShape *CreateShapeResponse `json:"createShape,omitempty"`

	// CreateSheetsChart: The result of creating a Google Sheets chart.
	CreateSheetsChart *CreateSheetsChartResponse `json:"createSheetsChart,omitempty"`

	// CreateSlide: The result of creating a slide.
	CreateSlide *CreateSlideResponse `json:"createSlide,omitempty"`

	// CreateTable: The result of creating a table.
	CreateTable *CreateTableResponse `json:"createTable,omitempty"`

	// CreateVideo: The result of creating a video.
	CreateVideo *CreateVideoResponse `json:"createVideo,omitempty"`

	// DuplicateObject: The result of duplicating an object.
	DuplicateObject *DuplicateObjectResponse `json:"duplicateObject,omitempty"`

	// GroupObjects: The result of grouping objects.
	GroupObjects *GroupObjectsResponse `json:"groupObjects,omitempty"`

	// ReplaceAllShapesWithImage: The result of replacing all shapes
	// matching some criteria with an
	// image.
	ReplaceAllShapesWithImage *ReplaceAllShapesWithImageResponse `json:"replaceAllShapesWithImage,omitempty"`

	// ReplaceAllShapesWithSheetsChart: The result of replacing all shapes
	// matching some criteria with a Google
	// Sheets chart.
	ReplaceAllShapesWithSheetsChart *ReplaceAllShapesWithSheetsChartResponse `json:"replaceAllShapesWithSheetsChart,omitempty"`

	// ReplaceAllText: The result of replacing text.
	ReplaceAllText *ReplaceAllTextResponse `json:"replaceAllText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreateImage") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CreateImage") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Response) MarshalJSON() ([]byte, error) {
	type NoMethod Response
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RgbColor: An RGB color.
type RgbColor struct {
	// Blue: The blue component of the color, from 0.0 to 1.0.
	Blue float64 `json:"blue,omitempty"`

	// Green: The green component of the color, from 0.0 to 1.0.
	Green float64 `json:"green,omitempty"`

	// Red: The red component of the color, from 0.0 to 1.0.
	Red float64 `json:"red,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Blue") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Blue") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RgbColor) MarshalJSON() ([]byte, error) {
	type NoMethod RgbColor
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *RgbColor) UnmarshalJSON(data []byte) error {
	type NoMethod RgbColor
	var s1 struct {
		Blue  gensupport.JSONFloat64 `json:"blue"`
		Green gensupport.JSONFloat64 `json:"green"`
		Red   gensupport.JSONFloat64 `json:"red"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Blue = float64(s1.Blue)
	s.Green = float64(s1.Green)
	s.Red = float64(s1.Red)
	return nil
}

// Shadow: The shadow properties of a page element.
//
// If these fields are unset, they may be inherited from a parent
// placeholder
// if it exists. If there is no parent, the fields will default to the
// value
// used for new page elements created in the Slides editor, which may
// depend on
// the page element kind.
type Shadow struct {
	// Alignment: The alignment point of the shadow, that sets the origin
	// for translate,
	// scale and skew of the shadow. This property is read-only.
	//
	// Possible values:
	//   "RECTANGLE_POSITION_UNSPECIFIED" - Unspecified.
	//   "TOP_LEFT" - Top left.
	//   "TOP_CENTER" - Top center.
	//   "TOP_RIGHT" - Top right.
	//   "LEFT_CENTER" - Left center.
	//   "CENTER" - Center.
	//   "RIGHT_CENTER" - Right center.
	//   "BOTTOM_LEFT" - Bottom left.
	//   "BOTTOM_CENTER" - Bottom center.
	//   "BOTTOM_RIGHT" - Bottom right.
	Alignment string `json:"alignment,omitempty"`

	// Alpha: The alpha of the shadow's color, from 0.0 to 1.0.
	Alpha float64 `json:"alpha,omitempty"`

	// BlurRadius: The radius of the shadow blur. The larger the radius, the
	// more diffuse the
	// shadow becomes.
	BlurRadius *Dimension `json:"blurRadius,omitempty"`

	// Color: The shadow color value.
	Color *OpaqueColor `json:"color,omitempty"`

	// PropertyState: The shadow property state.
	//
	// Updating the shadow on a page element will implicitly update this
	// field to
	// `RENDERED`, unless another value is specified in the same request. To
	// have
	// no shadow on a page element, set this field to `NOT_RENDERED`. In
	// this
	// case, any other shadow fields set in the same request will be
	// ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// RotateWithShape: Whether the shadow should rotate with the shape.
	// This property is
	// read-only.
	RotateWithShape bool `json:"rotateWithShape,omitempty"`

	// Transform: Transform that encodes the translate, scale, and skew of
	// the shadow,
	// relative to the alignment position.
	Transform *AffineTransform `json:"transform,omitempty"`

	// Type: The type of the shadow. This property is read-only.
	//
	// Possible values:
	//   "SHADOW_TYPE_UNSPECIFIED" - Unspecified shadow type.
	//   "OUTER" - Outer shadow.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alignment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Shadow) MarshalJSON() ([]byte, error) {
	type NoMethod Shadow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Shadow) UnmarshalJSON(data []byte) error {
	type NoMethod Shadow
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	return nil
}

// Shape: A PageElement kind representing a
// generic shape that does not have a more specific classification.
type Shape struct {
	// Placeholder: Placeholders are shapes that are inherit from
	// corresponding placeholders on
	// layouts and masters.
	//
	// If set, the shape is a placeholder shape and any inherited
	// properties
	// can be resolved by looking at the parent placeholder identified by
	// the
	// Placeholder.parent_object_id field.
	Placeholder *Placeholder `json:"placeholder,omitempty"`

	// ShapeProperties: The properties of the shape.
	ShapeProperties *ShapeProperties `json:"shapeProperties,omitempty"`

	// ShapeType: The type of the shape.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - The shape type that is not predefined.
	//   "TEXT_BOX" - Text box shape.
	//   "RECTANGLE" - Rectangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'rect'.
	//   "ROUND_RECTANGLE" - Round corner rectangle shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'roundRect'
	//   "ELLIPSE" - Ellipse shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ellipse'
	//   "ARC" - Curved arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'arc'
	//   "BENT_ARROW" - Bent arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentArrow'
	//   "BENT_UP_ARROW" - Bent up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'bentUpArrow'
	//   "BEVEL" - Bevel shape. Corresponds to ECMA-376 ST_ShapeType 'bevel'
	//   "BLOCK_ARC" - Block arc shape. Corresponds to ECMA-376 ST_ShapeType
	// 'blockArc'
	//   "BRACE_PAIR" - Brace pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracePair'
	//   "BRACKET_PAIR" - Bracket pair shape. Corresponds to ECMA-376
	// ST_ShapeType 'bracketPair'
	//   "CAN" - Can shape. Corresponds to ECMA-376 ST_ShapeType 'can'
	//   "CHEVRON" - Chevron shape. Corresponds to ECMA-376 ST_ShapeType
	// 'chevron'
	//   "CHORD" - Chord shape. Corresponds to ECMA-376 ST_ShapeType 'chord'
	//   "CLOUD" - Cloud shape. Corresponds to ECMA-376 ST_ShapeType 'cloud'
	//   "CORNER" - Corner shape. Corresponds to ECMA-376 ST_ShapeType
	// 'corner'
	//   "CUBE" - Cube shape. Corresponds to ECMA-376 ST_ShapeType 'cube'
	//   "CURVED_DOWN_ARROW" - Curved down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedDownArrow'
	//   "CURVED_LEFT_ARROW" - Curved left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedLeftArrow'
	//   "CURVED_RIGHT_ARROW" - Curved right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'curvedRightArrow'
	//   "CURVED_UP_ARROW" - Curved up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'curvedUpArrow'
	//   "DECAGON" - Decagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'decagon'
	//   "DIAGONAL_STRIPE" - Diagonal stripe shape. Corresponds to ECMA-376
	// ST_ShapeType 'diagStripe'
	//   "DIAMOND" - Diamond shape. Corresponds to ECMA-376 ST_ShapeType
	// 'diamond'
	//   "DODECAGON" - Dodecagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'dodecagon'
	//   "DONUT" - Donut shape. Corresponds to ECMA-376 ST_ShapeType 'donut'
	//   "DOUBLE_WAVE" - Double wave shape. Corresponds to ECMA-376
	// ST_ShapeType 'doubleWave'
	//   "DOWN_ARROW" - Down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'downArrow'
	//   "DOWN_ARROW_CALLOUT" - Callout down arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'downArrowCallout'
	//   "FOLDED_CORNER" - Folded corner shape. Corresponds to ECMA-376
	// ST_ShapeType 'foldedCorner'
	//   "FRAME" - Frame shape. Corresponds to ECMA-376 ST_ShapeType 'frame'
	//   "HALF_FRAME" - Half frame shape. Corresponds to ECMA-376
	// ST_ShapeType 'halfFrame'
	//   "HEART" - Heart shape. Corresponds to ECMA-376 ST_ShapeType 'heart'
	//   "HEPTAGON" - Heptagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'heptagon'
	//   "HEXAGON" - Hexagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'hexagon'
	//   "HOME_PLATE" - Home plate shape. Corresponds to ECMA-376
	// ST_ShapeType 'homePlate'
	//   "HORIZONTAL_SCROLL" - Horizontal scroll shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'horizontalScroll'
	//   "IRREGULAR_SEAL_1" - Irregular seal 1 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal1'
	//   "IRREGULAR_SEAL_2" - Irregular seal 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'irregularSeal2'
	//   "LEFT_ARROW" - Left arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftArrow'
	//   "LEFT_ARROW_CALLOUT" - Callout left arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftArrowCallout'
	//   "LEFT_BRACE" - Left brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBrace'
	//   "LEFT_BRACKET" - Left bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftBracket'
	//   "LEFT_RIGHT_ARROW" - Left right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightArrow'
	//   "LEFT_RIGHT_ARROW_CALLOUT" - Callout left right arrow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'leftRightArrowCallout'
	//   "LEFT_RIGHT_UP_ARROW" - Left right up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'leftRightUpArrow'
	//   "LEFT_UP_ARROW" - Left up arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'leftUpArrow'
	//   "LIGHTNING_BOLT" - Lightning bolt shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'lightningBolt'
	//   "MATH_DIVIDE" - Divide math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathDivide'
	//   "MATH_EQUAL" - Equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathEqual'
	//   "MATH_MINUS" - Minus math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMinus'
	//   "MATH_MULTIPLY" - Multiply math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathMultiply'
	//   "MATH_NOT_EQUAL" - Not equal math shape. Corresponds to ECMA-376
	// ST_ShapeType 'mathNotEqual'
	//   "MATH_PLUS" - Plus math shape. Corresponds to ECMA-376 ST_ShapeType
	// 'mathPlus'
	//   "MOON" - Moon shape. Corresponds to ECMA-376 ST_ShapeType 'moon'
	//   "NO_SMOKING" - No smoking shape. Corresponds to ECMA-376
	// ST_ShapeType 'noSmoking'
	//   "NOTCHED_RIGHT_ARROW" - Notched right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'notchedRightArrow'
	//   "OCTAGON" - Octagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'octagon'
	//   "PARALLELOGRAM" - Parallelogram shape. Corresponds to ECMA-376
	// ST_ShapeType 'parallelogram'
	//   "PENTAGON" - Pentagon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'pentagon'
	//   "PIE" - Pie shape. Corresponds to ECMA-376 ST_ShapeType 'pie'
	//   "PLAQUE" - Plaque shape. Corresponds to ECMA-376 ST_ShapeType
	// 'plaque'
	//   "PLUS" - Plus shape. Corresponds to ECMA-376 ST_ShapeType 'plus'
	//   "QUAD_ARROW" - Quad-arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'quadArrow'
	//   "QUAD_ARROW_CALLOUT" - Callout quad-arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'quadArrowCallout'
	//   "RIBBON" - Ribbon shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon'
	//   "RIBBON_2" - Ribbon 2 shape. Corresponds to ECMA-376 ST_ShapeType
	// 'ribbon2'
	//   "RIGHT_ARROW" - Right arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightArrow'
	//   "RIGHT_ARROW_CALLOUT" - Callout right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'rightArrowCallout'
	//   "RIGHT_BRACE" - Right brace shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBrace'
	//   "RIGHT_BRACKET" - Right bracket shape. Corresponds to ECMA-376
	// ST_ShapeType 'rightBracket'
	//   "ROUND_1_RECTANGLE" - One round corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'round1Rect'
	//   "ROUND_2_DIAGONAL_RECTANGLE" - Two diagonal round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2DiagRect'
	//   "ROUND_2_SAME_RECTANGLE" - Two same-side round corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'round2SameRect'
	//   "RIGHT_TRIANGLE" - Right triangle shape. Corresponds to ECMA-376
	// ST_ShapeType 'rtTriangle'
	//   "SMILEY_FACE" - Smiley face shape. Corresponds to ECMA-376
	// ST_ShapeType 'smileyFace'
	//   "SNIP_1_RECTANGLE" - One snip corner rectangle shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'snip1Rect'
	//   "SNIP_2_DIAGONAL_RECTANGLE" - Two diagonal snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2DiagRect'
	//   "SNIP_2_SAME_RECTANGLE" - Two same-side snip corner rectangle
	// shape. Corresponds to ECMA-376
	// ST_ShapeType 'snip2SameRect'
	//   "SNIP_ROUND_RECTANGLE" - One snip one round corner rectangle shape.
	// Corresponds to ECMA-376
	// ST_ShapeType 'snipRoundRect'
	//   "STAR_10" - Ten pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star10'
	//   "STAR_12" - Twelve pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star12'
	//   "STAR_16" - Sixteen pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star16'
	//   "STAR_24" - Twenty four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star24'
	//   "STAR_32" - Thirty two pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'star32'
	//   "STAR_4" - Four pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star4'
	//   "STAR_5" - Five pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star5'
	//   "STAR_6" - Six pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star6'
	//   "STAR_7" - Seven pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star7'
	//   "STAR_8" - Eight pointed star shape. Corresponds to ECMA-376
	// ST_ShapeType 'star8'
	//   "STRIPED_RIGHT_ARROW" - Striped right arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'stripedRightArrow'
	//   "SUN" - Sun shape. Corresponds to ECMA-376 ST_ShapeType 'sun'
	//   "TRAPEZOID" - Trapezoid shape. Corresponds to ECMA-376 ST_ShapeType
	// 'trapezoid'
	//   "TRIANGLE" - Triangle shape. Corresponds to ECMA-376 ST_ShapeType
	// 'triangle'
	//   "UP_ARROW" - Up arrow shape. Corresponds to ECMA-376 ST_ShapeType
	// 'upArrow'
	//   "UP_ARROW_CALLOUT" - Callout up arrow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'upArrowCallout'
	//   "UP_DOWN_ARROW" - Up down arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'upDownArrow'
	//   "UTURN_ARROW" - U-turn arrow shape. Corresponds to ECMA-376
	// ST_ShapeType 'uturnArrow'
	//   "VERTICAL_SCROLL" - Vertical scroll shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'verticalScroll'
	//   "WAVE" - Wave shape. Corresponds to ECMA-376 ST_ShapeType 'wave'
	//   "WEDGE_ELLIPSE_CALLOUT" - Callout wedge ellipse shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'wedgeEllipseCallout'
	//   "WEDGE_RECTANGLE_CALLOUT" - Callout wedge rectangle shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRectCallout'
	//   "WEDGE_ROUND_RECTANGLE_CALLOUT" - Callout wedge round rectangle
	// shape. Corresponds to ECMA-376 ST_ShapeType
	// 'wedgeRoundRectCallout'
	//   "FLOW_CHART_ALTERNATE_PROCESS" - Alternate process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartAlternateProcess'
	//   "FLOW_CHART_COLLATE" - Collate flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartCollate'
	//   "FLOW_CHART_CONNECTOR" - Connector flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartConnector'
	//   "FLOW_CHART_DECISION" - Decision flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDecision'
	//   "FLOW_CHART_DELAY" - Delay flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartDelay'
	//   "FLOW_CHART_DISPLAY" - Display flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartDisplay'
	//   "FLOW_CHART_DOCUMENT" - Document flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartDocument'
	//   "FLOW_CHART_EXTRACT" - Extract flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartExtract'
	//   "FLOW_CHART_INPUT_OUTPUT" - Input output flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartInputOutput'
	//   "FLOW_CHART_INTERNAL_STORAGE" - Internal storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartInternalStorage'
	//   "FLOW_CHART_MAGNETIC_DISK" - Magnetic disk flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDisk'
	//   "FLOW_CHART_MAGNETIC_DRUM" - Magnetic drum flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticDrum'
	//   "FLOW_CHART_MAGNETIC_TAPE" - Magnetic tape flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMagneticTape'
	//   "FLOW_CHART_MANUAL_INPUT" - Manual input flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartManualInput'
	//   "FLOW_CHART_MANUAL_OPERATION" - Manual operation flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartManualOperation'
	//   "FLOW_CHART_MERGE" - Merge flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartMerge'
	//   "FLOW_CHART_MULTIDOCUMENT" - Multi-document flow shape. Corresponds
	// to ECMA-376 ST_ShapeType
	// 'flowChartMultidocument'
	//   "FLOW_CHART_OFFLINE_STORAGE" - Offline storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOfflineStorage'
	//   "FLOW_CHART_OFFPAGE_CONNECTOR" - Off-page connector flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOffpageConnector'
	//   "FLOW_CHART_ONLINE_STORAGE" - Online storage flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartOnlineStorage'
	//   "FLOW_CHART_OR" - Or flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartOr'
	//   "FLOW_CHART_PREDEFINED_PROCESS" - Predefined process flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartPredefinedProcess'
	//   "FLOW_CHART_PREPARATION" - Preparation flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPreparation'
	//   "FLOW_CHART_PROCESS" - Process flow shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'flowChartProcess'
	//   "FLOW_CHART_PUNCHED_CARD" - Punched card flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedCard'
	//   "FLOW_CHART_PUNCHED_TAPE" - Punched tape flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartPunchedTape'
	//   "FLOW_CHART_SORT" - Sort flow shape. Corresponds to ECMA-376
	// ST_ShapeType 'flowChartSort'
	//   "FLOW_CHART_SUMMING_JUNCTION" - Summing junction flow shape.
	// Corresponds to ECMA-376 ST_ShapeType
	// 'flowChartSummingJunction'
	//   "FLOW_CHART_TERMINATOR" - Terminator flow shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'flowChartTerminator'
	//   "ARROW_EAST" - East arrow shape.
	//   "ARROW_NORTH_EAST" - Northeast arrow shape.
	//   "ARROW_NORTH" - North arrow shape.
	//   "SPEECH" - Speech shape.
	//   "STARBURST" - Star burst shape.
	//   "TEARDROP" - Teardrop shape. Corresponds to ECMA-376 ST_ShapeType
	// 'teardrop'
	//   "ELLIPSE_RIBBON" - Ellipse ribbon shape. Corresponds to ECMA-376
	// ST_ShapeType
	// 'ellipseRibbon'
	//   "ELLIPSE_RIBBON_2" - Ellipse ribbon 2 shape. Corresponds to
	// ECMA-376 ST_ShapeType
	// 'ellipseRibbon2'
	//   "CLOUD_CALLOUT" - Callout cloud shape. Corresponds to ECMA-376
	// ST_ShapeType 'cloudCallout'
	//   "CUSTOM" - Custom shape.
	ShapeType string `json:"shapeType,omitempty"`

	// Text: The text content of the shape.
	Text *TextContent `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Placeholder") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Placeholder") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Shape) MarshalJSON() ([]byte, error) {
	type NoMethod Shape
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShapeBackgroundFill: The shape background fill.
type ShapeBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a shape will implicitly update this field
	// to
	// `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a shape, set this field to `NOT_RENDERED`. In this
	// case,
	// any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ShapeBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod ShapeBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShapeProperties: The properties of a Shape.
//
// If the shape is a placeholder shape as determined by the
// placeholder field, then these
// properties may be inherited from a parent placeholder
// shape.
// Determining the rendered value of the property depends on the
// corresponding
// property_state field value.
type ShapeProperties struct {
	// ContentAlignment: The alignment of the content in the shape. If
	// unspecified,
	// the alignment is inherited from a parent placeholder if it exists. If
	// the
	// shape has no parent, the default alignment matches the alignment for
	// new
	// shapes created in the Slides editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from
	// the parent if it exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// Link: The hyperlink destination of the shape. If unset, there is no
	// link. Links
	// are not inherited from parent placeholders.
	Link *Link `json:"link,omitempty"`

	// Outline: The outline of the shape. If unset, the outline is inherited
	// from a
	// parent placeholder if it exists. If the shape has no parent, then
	// the
	// default outline depends on the shape type, matching the defaults
	// for
	// new shapes created in the Slides editor.
	Outline *Outline `json:"outline,omitempty"`

	// Shadow: The shadow properties of the shape. If unset, the shadow is
	// inherited from
	// a parent placeholder if it exists. If the shape has no parent, then
	// the
	// default shadow matches the defaults for new shapes created in the
	// Slides
	// editor. This property is read-only.
	Shadow *Shadow `json:"shadow,omitempty"`

	// ShapeBackgroundFill: The background fill of the shape. If unset, the
	// background fill is
	// inherited from a parent placeholder if it exists. If the shape has
	// no
	// parent, then the default background fill depends on the shape
	// type,
	// matching the defaults for new shapes created in the Slides editor.
	ShapeBackgroundFill *ShapeBackgroundFill `json:"shapeBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentAlignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentAlignment") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ShapeProperties) MarshalJSON() ([]byte, error) {
	type NoMethod ShapeProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SheetsChart: A PageElement kind representing
// a linked chart embedded from Google Sheets.
type SheetsChart struct {
	// ChartId: The ID of the specific chart in the Google Sheets
	// spreadsheet that is
	// embedded.
	ChartId int64 `json:"chartId,omitempty"`

	// ContentUrl: The URL of an image of the embedded chart, with a default
	// lifetime of 30
	// minutes. This URL is tagged with the account of the requester. Anyone
	// with
	// the URL effectively accesses the image as the original requester.
	// Access to
	// the image may be lost if the presentation's sharing settings change.
	ContentUrl string `json:"contentUrl,omitempty"`

	// SheetsChartProperties: The properties of the Sheets chart.
	SheetsChartProperties *SheetsChartProperties `json:"sheetsChartProperties,omitempty"`

	// SpreadsheetId: The ID of the Google Sheets spreadsheet that contains
	// the source chart.
	SpreadsheetId string `json:"spreadsheetId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ChartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SheetsChart) MarshalJSON() ([]byte, error) {
	type NoMethod SheetsChart
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SheetsChartProperties: The properties of the SheetsChart.
type SheetsChartProperties struct {
	// ChartImageProperties: The properties of the embedded chart image.
	ChartImageProperties *ImageProperties `json:"chartImageProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ChartImageProperties") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ChartImageProperties") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SheetsChartProperties) MarshalJSON() ([]byte, error) {
	type NoMethod SheetsChartProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Size: A width and height.
type Size struct {
	// Height: The height of the object.
	Height *Dimension `json:"height,omitempty"`

	// Width: The width of the object.
	Width *Dimension `json:"width,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Height") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Height") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Size) MarshalJSON() ([]byte, error) {
	type NoMethod Size
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SlideProperties: The properties of Page that are only
// relevant for pages with page_type SLIDE.
type SlideProperties struct {
	// LayoutObjectId: The object ID of the layout that this slide is based
	// on. This property is
	// read-only.
	LayoutObjectId string `json:"layoutObjectId,omitempty"`

	// MasterObjectId: The object ID of the master that this slide is based
	// on. This property is
	// read-only.
	MasterObjectId string `json:"masterObjectId,omitempty"`

	// NotesPage: The notes page that this slide is associated with. It
	// defines the visual
	// appearance of a notes page when printing or exporting slides with
	// speaker
	// notes. A notes page inherits properties from the
	// notes master.
	// The placeholder shape with type BODY on the notes page contains the
	// speaker
	// notes for this slide. The ID of this shape is identified by
	// the
	// speakerNotesObjectId field.
	// The notes page is read-only except for the text content and styles of
	// the
	// speaker notes shape. This property is read-only.
	NotesPage *Page `json:"notesPage,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LayoutObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LayoutObjectId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SlideProperties) MarshalJSON() ([]byte, error) {
	type NoMethod SlideProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SolidFill: A solid color fill. The page or page element is filled
// entirely with the
// specified color value.
//
// If any field is unset, its value may be inherited from a parent
// placeholder
// if it exists.
type SolidFill struct {
	// Alpha: The fraction of this `color` that should be applied to the
	// pixel.
	// That is, the final pixel color is defined by the equation:
	//
	//   pixel color = alpha * (color) + (1.0 - alpha) * (background
	// color)
	//
	// This means that a value of 1.0 corresponds to a solid color,
	// whereas
	// a value of 0.0 corresponds to a completely transparent color.
	Alpha float64 `json:"alpha,omitempty"`

	// Color: The color value of the solid fill.
	Color *OpaqueColor `json:"color,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alpha") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alpha") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SolidFill) MarshalJSON() ([]byte, error) {
	type NoMethod SolidFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *SolidFill) UnmarshalJSON(data []byte) error {
	type NoMethod SolidFill
	var s1 struct {
		Alpha gensupport.JSONFloat64 `json:"alpha"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Alpha = float64(s1.Alpha)
	return nil
}

// StretchedPictureFill: The stretched picture fill. The page or page
// element is filled entirely with
// the specified picture. The picture is stretched to fit its container.
type StretchedPictureFill struct {
	// ContentUrl: Reading the content_url:
	//
	// An URL to a picture with a default lifetime of 30 minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the picture as the original requester. Access to
	// the
	// picture may be lost if the presentation's sharing settings
	// change.
	//
	// Writing the content_url:
	//
	// The picture is fetched once at insertion time and a copy is stored
	// for
	// display inside the presentation. Pictures must be less than 50MB in
	// size,
	// cannot exceed 25 megapixels, and must be in one of PNG, JPEG, or
	// GIF
	// format.
	//
	// The provided URL can be at most 2 kB in length.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Size: The original size of the picture fill. This field is read-only.
	Size *Size `json:"size,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StretchedPictureFill) MarshalJSON() ([]byte, error) {
	type NoMethod StretchedPictureFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// SubstringMatchCriteria: A criteria that matches a specific string of
// text in a shape or table.
type SubstringMatchCriteria struct {
	// MatchCase: Indicates whether the search should respect case:
	//
	// - `True`: the search is case sensitive.
	// - `False`: the search is case insensitive.
	MatchCase bool `json:"matchCase,omitempty"`

	// Text: The text to search for in the shape or table.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MatchCase") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MatchCase") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *SubstringMatchCriteria) MarshalJSON() ([]byte, error) {
	type NoMethod SubstringMatchCriteria
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Table: A PageElement kind representing a
// table.
type Table struct {
	// Columns: Number of columns in the table.
	Columns int64 `json:"columns,omitempty"`

	// HorizontalBorderRows: Properties of horizontal cell borders.
	//
	// A table's horizontal cell borders are represented as a grid. The grid
	// has
	// one more row than the number of rows in the table and the same number
	// of
	// columns as the table. For example, if the table is 3 x 3, its
	// horizontal
	// borders will be represented as a grid with 4 rows and 3 columns.
	HorizontalBorderRows []*TableBorderRow `json:"horizontalBorderRows,omitempty"`

	// Rows: Number of rows in the table.
	Rows int64 `json:"rows,omitempty"`

	// TableColumns: Properties of each column.
	TableColumns []*TableColumnProperties `json:"tableColumns,omitempty"`

	// TableRows: Properties and contents of each row.
	//
	// Cells that span multiple rows are contained in only one of these rows
	// and
	// have a row_span greater
	// than 1.
	TableRows []*TableRow `json:"tableRows,omitempty"`

	// VerticalBorderRows: Properties of vertical cell borders.
	//
	// A table's vertical cell borders are represented as a grid. The grid
	// has the
	// same number of rows as the table and one more column than the number
	// of
	// columns in the table. For example, if the table is 3 x 3, its
	// vertical
	// borders will be represented as a grid with 3 rows and 4 columns.
	VerticalBorderRows []*TableBorderRow `json:"verticalBorderRows,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Columns") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Columns") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Table) MarshalJSON() ([]byte, error) {
	type NoMethod Table
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderCell: The properties of each border cell.
type TableBorderCell struct {
	// Location: The location of the border within the border table.
	Location *TableCellLocation `json:"location,omitempty"`

	// TableBorderProperties: The border properties.
	TableBorderProperties *TableBorderProperties `json:"tableBorderProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Location") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderCell) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderFill: The fill of the border.
type TableBorderFill struct {
	// SolidFill: Solid fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SolidFill") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "SolidFill") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderFill) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderProperties: The border styling properties of
// the
// TableBorderCell.
type TableBorderProperties struct {
	// DashStyle: The dash style of the border.
	//
	// Possible values:
	//   "DASH_STYLE_UNSPECIFIED" - Unspecified dash style.
	//   "SOLID" - Solid line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'solid'.
	// This is the default dash style.
	//   "DOT" - Dotted line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dot'.
	//   "DASH" - Dashed line. Corresponds to ECMA-376 ST_PresetLineDashVal
	// value 'dash'.
	//   "DASH_DOT" - Alternating dashes and dots. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'dashDot'.
	//   "LONG_DASH" - Line with large dashes. Corresponds to ECMA-376
	// ST_PresetLineDashVal
	// value 'lgDash'.
	//   "LONG_DASH_DOT" - Alternating large dashes and dots. Corresponds to
	// ECMA-376
	// ST_PresetLineDashVal value 'lgDashDot'.
	DashStyle string `json:"dashStyle,omitempty"`

	// TableBorderFill: The fill of the table border.
	TableBorderFill *TableBorderFill `json:"tableBorderFill,omitempty"`

	// Weight: The thickness of the border.
	Weight *Dimension `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DashStyle") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DashStyle") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableBorderRow: Contents of each border row in a table.
type TableBorderRow struct {
	// TableBorderCells: Properties of each border cell. When a border's
	// adjacent table cells are
	// merged, it is not included in the response.
	TableBorderCells []*TableBorderCell `json:"tableBorderCells,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TableBorderCells") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TableBorderCells") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TableBorderRow) MarshalJSON() ([]byte, error) {
	type NoMethod TableBorderRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCell: Properties and contents of each table cell.
type TableCell struct {
	// ColumnSpan: Column span of the cell.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// Location: The location of the cell within the table.
	Location *TableCellLocation `json:"location,omitempty"`

	// RowSpan: Row span of the cell.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// TableCellProperties: The properties of the table cell.
	TableCellProperties *TableCellProperties `json:"tableCellProperties,omitempty"`

	// Text: The text content of the cell.
	Text *TextContent `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnSpan") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnSpan") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCell) MarshalJSON() ([]byte, error) {
	type NoMethod TableCell
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellBackgroundFill: The table cell background fill.
type TableCellBackgroundFill struct {
	// PropertyState: The background fill property state.
	//
	// Updating the fill on a table cell will implicitly update this
	// field
	// to `RENDERED`, unless another value is specified in the same request.
	// To
	// have no fill on a table cell, set this field to `NOT_RENDERED`. In
	// this
	// case, any other fill fields set in the same request will be ignored.
	//
	// Possible values:
	//   "RENDERED" - If a property's state is RENDERED, then the element
	// has the corresponding
	// property when rendered on a page. If the element is a placeholder
	// shape as
	// determined by the placeholder
	// field, and it inherits from a placeholder shape, the corresponding
	// field
	// may be unset, meaning that the property value is inherited from a
	// parent
	// placeholder. If the element does not inherit, then the field will
	// contain
	// the rendered value. This is the default value.
	//   "NOT_RENDERED" - If a property's state is NOT_RENDERED, then the
	// element does not have the
	// corresponding property when rendered on a page. However, the field
	// may
	// still be set so it can be inherited by child shapes. To remove a
	// property
	// from a rendered element, set its property_state to NOT_RENDERED.
	//   "INHERIT" - If a property's state is INHERIT, then the property
	// state uses the value of
	// corresponding `property_state` field on the parent shape. Elements
	// that do
	// not inherit will never have an INHERIT property state.
	PropertyState string `json:"propertyState,omitempty"`

	// SolidFill: Solid color fill.
	SolidFill *SolidFill `json:"solidFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PropertyState") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PropertyState") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCellBackgroundFill) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellBackgroundFill
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellLocation: A location of a single table cell within a table.
type TableCellLocation struct {
	// ColumnIndex: The 0-based column index.
	ColumnIndex int64 `json:"columnIndex,omitempty"`

	// RowIndex: The 0-based row index.
	RowIndex int64 `json:"rowIndex,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnIndex") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableCellLocation) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellLocation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableCellProperties: The properties of the TableCell.
type TableCellProperties struct {
	// ContentAlignment: The alignment of the content in the table cell. The
	// default alignment
	// matches the alignment for newly created table cells in the Slides
	// editor.
	//
	// Possible values:
	//   "CONTENT_ALIGNMENT_UNSPECIFIED" - An unspecified content alignment.
	// The content alignment is inherited from
	// the parent if it exists.
	//   "CONTENT_ALIGNMENT_UNSUPPORTED" - An unsupported content alignment.
	//   "TOP" - An alignment that aligns the content to the top of the
	// content holder.
	// Corresponds to ECMA-376 ST_TextAnchoringType 't'.
	//   "MIDDLE" - An alignment that aligns the content to the middle of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'ctr'.
	//   "BOTTOM" - An alignment that aligns the content to the bottom of
	// the content
	// holder. Corresponds to ECMA-376 ST_TextAnchoringType 'b'.
	ContentAlignment string `json:"contentAlignment,omitempty"`

	// TableCellBackgroundFill: The background fill of the table cell. The
	// default fill matches the fill
	// for newly created table cells in the Slides editor.
	TableCellBackgroundFill *TableCellBackgroundFill `json:"tableCellBackgroundFill,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContentAlignment") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentAlignment") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TableCellProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableCellProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableColumnProperties: Properties of each column in a table.
type TableColumnProperties struct {
	// ColumnWidth: Width of a column.
	ColumnWidth *Dimension `json:"columnWidth,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnWidth") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnWidth") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableColumnProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableColumnProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRange: A table range represents a reference to a subset of a
// table.
//
// It's important to note that the cells specified by a table range do
// not
// necessarily form a rectangle. For example, let's say we have a 3 x 3
// table
// where all the cells of the last row are merged together. The table
// looks
// like this:
//
//
//      [             ]
//
// A table range with location = (0, 0), row span = 3 and column span =
// 2
// specifies the following cells:
//
//       x     x
//      [ x    x    x ]
type TableRange struct {
	// ColumnSpan: The column span of the table range.
	ColumnSpan int64 `json:"columnSpan,omitempty"`

	// Location: The starting location of the table range.
	Location *TableCellLocation `json:"location,omitempty"`

	// RowSpan: The row span of the table range.
	RowSpan int64 `json:"rowSpan,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnSpan") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnSpan") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRange) MarshalJSON() ([]byte, error) {
	type NoMethod TableRange
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRow: Properties and contents of each row in a table.
type TableRow struct {
	// RowHeight: Height of a row.
	RowHeight *Dimension `json:"rowHeight,omitempty"`

	// TableCells: Properties and contents of each cell.
	//
	// Cells that span multiple columns are represented only once with
	// a
	// column_span greater
	// than 1. As a result, the length of this collection does not always
	// match
	// the number of columns of the entire table.
	TableCells []*TableCell `json:"tableCells,omitempty"`

	// TableRowProperties: Properties of the row.
	TableRowProperties *TableRowProperties `json:"tableRowProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RowHeight") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RowHeight") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRow) MarshalJSON() ([]byte, error) {
	type NoMethod TableRow
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TableRowProperties: Properties of each row in a table.
type TableRowProperties struct {
	// MinRowHeight: Minimum height of the row. The row will be rendered in
	// the Slides editor at
	// a height equal to or greater than this value in order to show all the
	// text
	// in the row's cell(s).
	MinRowHeight *Dimension `json:"minRowHeight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MinRowHeight") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MinRowHeight") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TableRowProperties) MarshalJSON() ([]byte, error) {
	type NoMethod TableRowProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextContent: The general text content. The text must reside in a
// compatible shape (e.g.
// text box or rectangle) or a table cell in a page.
type TextContent struct {
	// Lists: The bulleted lists contained in this text, keyed by list ID.
	Lists map[string]List `json:"lists,omitempty"`

	// TextElements: The text contents broken down into its component parts,
	// including styling
	// information. This property is read-only.
	TextElements []*TextElement `json:"textElements,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Lists") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Lists") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextContent) MarshalJSON() ([]byte, error) {
	type NoMethod TextContent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextElement: A TextElement describes the content of a range of
// indices in the text content
// of a Shape or TableCell.
type TextElement struct {
	// AutoText: A TextElement representing a spot in the text that is
	// dynamically
	// replaced with content that can change over time.
	AutoText *AutoText `json:"autoText,omitempty"`

	// EndIndex: The zero-based end index of this text element, exclusive,
	// in Unicode code
	// units.
	EndIndex int64 `json:"endIndex,omitempty"`

	// ParagraphMarker: A marker representing the beginning of a new
	// paragraph.
	//
	// The `start_index` and `end_index` of this TextElement represent
	// the
	// range of the paragraph. Other TextElements with an index range
	// contained
	// inside this paragraph's range are considered to be part of
	// this
	// paragraph. The range of indices of two separate paragraphs will
	// never
	// overlap.
	ParagraphMarker *ParagraphMarker `json:"paragraphMarker,omitempty"`

	// StartIndex: The zero-based start index of this text element, in
	// Unicode code units.
	StartIndex int64 `json:"startIndex,omitempty"`

	// TextRun: A TextElement representing a run of text where all of the
	// characters
	// in the run have the same TextStyle.
	//
	// The `start_index` and `end_index` of TextRuns will always be
	// fully
	// contained in the index range of a single `paragraph_marker`
	// TextElement.
	// In other words, a TextRun will never span multiple paragraphs.
	TextRun *TextRun `json:"textRun,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoText") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextElement) MarshalJSON() ([]byte, error) {
	type NoMethod TextElement
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextRun: A TextElement kind that represents a run of text that all
// has the same
// styling.
type TextRun struct {
	// Content: The text of this run.
	Content string `json:"content,omitempty"`

	// Style: The styling applied to this run.
	Style *TextStyle `json:"style,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Content") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TextRun) MarshalJSON() ([]byte, error) {
	type NoMethod TextRun
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TextStyle: Represents the styling that can be applied to a
// TextRun.
//
// If this text is contained in a shape with a parent placeholder, then
// these text styles may be
// inherited from the parent. Which text styles are inherited depend on
// the
// nesting level of lists:
//
// * A text run in a paragraph that is not in a list will inherit its
// text style
//   from the the newline character in the paragraph at the 0 nesting
// level of
//   the list inside the parent placeholder.
// * A text run in a paragraph that is in a list will inherit its text
// style
//   from the newline character in the paragraph at its corresponding
// nesting
//   level of the list inside the parent placeholder.
//
// Inherited text styles are represented as unset fields in this
// message. If
// text is contained in a shape without a parent placeholder, unsetting
// these
// fields will revert the style to a value matching the defaults in the
// Slides
// editor.
type TextStyle struct {
	// BackgroundColor: The background color of the text. If set, the color
	// is either opaque or
	// transparent, depending on if the `opaque_color` field in it is set.
	BackgroundColor *OptionalColor `json:"backgroundColor,omitempty"`

	// BaselineOffset: The text's vertical offset from its normal
	// position.
	//
	// Text with `SUPERSCRIPT` or `SUBSCRIPT` baseline offsets is
	// automatically
	// rendered in a smaller font size, computed based on the `font_size`
	// field.
	// The `font_size` itself is not affected by changes in this field.
	//
	// Possible values:
	//   "BASELINE_OFFSET_UNSPECIFIED" - The text's baseline offset is
	// inherited from the parent.
	//   "NONE" - The text is not vertically offset.
	//   "SUPERSCRIPT" - The text is vertically offset upwards
	// (superscript).
	//   "SUBSCRIPT" - The text is vertically offset downwards (subscript).
	BaselineOffset string `json:"baselineOffset,omitempty"`

	// Bold: Whether or not the text is rendered as bold.
	Bold bool `json:"bold,omitempty"`

	// FontFamily: The font family of the text.
	//
	// The font family can be any font from the Font menu in Slides or
	// from
	// [Google Fonts] (https://fonts.google.com/). If the font name
	// is
	// unrecognized, the text is rendered in `Arial`.
	//
	// Some fonts can affect the weight of the text. If an update
	// request
	// specifies values for both `font_family` and `bold`, the
	// explicitly-set
	// `bold` value is used.
	FontFamily string `json:"fontFamily,omitempty"`

	// FontSize: The size of the text's font. When read, the `font_size`
	// will specified in
	// points.
	FontSize *Dimension `json:"fontSize,omitempty"`

	// ForegroundColor: The color of the text itself. If set, the color is
	// either opaque or
	// transparent, depending on if the `opaque_color` field in it is set.
	ForegroundColor *OptionalColor `json:"foregroundColor,omitempty"`

	// Italic: Whether or not the text is italicized.
	Italic bool `json:"italic,omitempty"`

	// Link: The hyperlink destination of the text. If unset, there is no
	// link. Links
	// are not inherited from parent text.
	//
	// Changing the link in an update request causes some other changes to
	// the
	// text style of the range:
	//
	// * When setting a link, the text foreground color will be set to
	//   ThemeColorType.HYPERLINK and the text will
	//   be underlined. If these fields are modified in the same
	//   request, those values will be used instead of the link defaults.
	// * Setting a link on a text range that overlaps with an existing link
	// will
	//   also update the existing link to point to the new URL.
	// * Links are not settable on newline characters. As a result, setting
	// a link
	//   on a text range that crosses a paragraph boundary, such as
	// "ABC\n123",
	//   will separate the newline character(s) into their own text runs.
	// The
	//   link will be applied separately to the runs before and after the
	// newline.
	// * Removing a link will update the text style of the range to match
	// the
	//   style of the preceding text (or the default text styles if the
	// preceding
	//   text is another link) unless different styles are being set in the
	// same
	//   request.
	Link *Link `json:"link,omitempty"`

	// SmallCaps: Whether or not the text is in small capital letters.
	SmallCaps bool `json:"smallCaps,omitempty"`

	// Strikethrough: Whether or not the text is struck through.
	Strikethrough bool `json:"strikethrough,omitempty"`

	// Underline: Whether or not the text is underlined.
	Underline bool `json:"underline,omitempty"`

	// WeightedFontFamily: The font family and rendered weight of the
	// text.
	//
	// This field is an extension of `font_family` meant to support explicit
	// font
	// weights without breaking backwards compatibility. As such, when
	// reading the
	// style of a range of text, the value of
	// `weighted_font_family#font_family`
	// will always be equal to that of `font_family`. However, when writing,
	// if
	// both fields are included in the field mask (either explicitly or
	// through
	// the wildcard "*"), their values are reconciled as follows:
	//
	// * If `font_family` is set and `weighted_font_family` is not, the
	// value of
	//   `font_family` is applied with weight `400` ("normal").
	// * If both fields are set, the value of `font_family` must match that
	// of
	//   `weighted_font_family#font_family`. If so, the font family and
	// weight of
	//   `weighted_font_family` is applied. Otherwise, a 400 bad request
	// error is
	//   returned.
	// * If `weighted_font_family` is set and `font_family` is not, the
	// font
	//   family and weight of `weighted_font_family` is applied.
	// * If neither field is set, the font family and weight of the text
	// inherit
	//   from the parent. Note that these properties cannot inherit
	// separately
	//   from each other.
	//
	// If an update request specifies values for both `weighted_font_family`
	// and
	// `bold`, the `weighted_font_family` is applied first, then `bold`.
	//
	// If `weighted_font_family#weight` is not set, it defaults to
	// `400`.
	//
	// If `weighted_font_family` is set, then
	// `weighted_font_family#font_family`
	// must also be set with a non-empty value. Otherwise, a 400 bad request
	// error
	// is returned.
	WeightedFontFamily *WeightedFontFamily `json:"weightedFontFamily,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BackgroundColor") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BackgroundColor") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TextStyle) MarshalJSON() ([]byte, error) {
	type NoMethod TextStyle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ThemeColorPair: A pair mapping a theme color type to the concrete
// color it represents.
type ThemeColorPair struct {
	// Color: The concrete color corresponding to the theme color type
	// above.
	Color *RgbColor `json:"color,omitempty"`

	// Type: The type of the theme color.
	//
	// Possible values:
	//   "THEME_COLOR_TYPE_UNSPECIFIED" - Unspecified theme color. This
	// value should not be used.
	//   "DARK1" - Represents the first dark color.
	//   "LIGHT1" - Represents the first light color.
	//   "DARK2" - Represents the second dark color.
	//   "LIGHT2" - Represents the second light color.
	//   "ACCENT1" - Represents the first accent color.
	//   "ACCENT2" - Represents the second accent color.
	//   "ACCENT3" - Represents the third accent color.
	//   "ACCENT4" - Represents the fourth accent color.
	//   "ACCENT5" - Represents the fifth accent color.
	//   "ACCENT6" - Represents the sixth accent color.
	//   "HYPERLINK" - Represents the color to use for hyperlinks.
	//   "FOLLOWED_HYPERLINK" - Represents the color to use for visited
	// hyperlinks.
	//   "TEXT1" - Represents the first text color.
	//   "BACKGROUND1" - Represents the first background color.
	//   "TEXT2" - Represents the second text color.
	//   "BACKGROUND2" - Represents the second background color.
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Color") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Color") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ThemeColorPair) MarshalJSON() ([]byte, error) {
	type NoMethod ThemeColorPair
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Thumbnail: The thumbnail of a page.
type Thumbnail struct {
	// ContentUrl: The content URL of the thumbnail image.
	//
	// The URL to the image has a default lifetime of 30 minutes.
	// This URL is tagged with the account of the requester. Anyone with the
	// URL
	// effectively accesses the image as the original requester. Access to
	// the
	// image may be lost if the presentation's sharing settings change.
	// The mime type of the thumbnail image is the same as specified in
	// the
	// `GetPageThumbnailRequest`.
	ContentUrl string `json:"contentUrl,omitempty"`

	// Height: The positive height in pixels of the thumbnail image.
	Height int64 `json:"height,omitempty"`

	// Width: The positive width in pixels of the thumbnail image.
	Width int64 `json:"width,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ContentUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ContentUrl") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Thumbnail) MarshalJSON() ([]byte, error) {
	type NoMethod Thumbnail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UngroupObjectsRequest: Ungroups objects, such as groups.
type UngroupObjectsRequest struct {
	// ObjectIds: The object IDs of the objects to ungroup.
	//
	// Only groups that are not inside other
	// groups can be ungrouped. All the groups
	// should be on the same page. The group itself is deleted. The visual
	// sizes
	// and positions of all the children are preserved.
	ObjectIds []string `json:"objectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectIds") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectIds") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UngroupObjectsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UngroupObjectsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UnmergeTableCellsRequest: Unmerges cells in a Table.
type UnmergeTableCellsRequest struct {
	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableRange: The table range specifying which cells of the table to
	// unmerge.
	//
	// All merged cells in this range will be unmerged, and cells that are
	// already
	// unmerged will not be affected. If the range has no merged cells,
	// the
	// request will do nothing. If there is text in any of the merged cells,
	// the
	// text will remain in the upper-left ("head") cell of the resulting
	// block of
	// unmerged cells.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObjectId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObjectId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UnmergeTableCellsRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UnmergeTableCellsRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateImagePropertiesRequest: Update the properties of an Image.
type UpdateImagePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `imageProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the image outline color, set `fields`
	// to
	// "outline.outlineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ImageProperties: The image properties to update.
	ImageProperties *ImageProperties `json:"imageProperties,omitempty"`

	// ObjectId: The object ID of the image the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateImagePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateImagePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateLineCategoryRequest: Updates the category of a line.
type UpdateLineCategoryRequest struct {
	// LineCategory: The line category to update to.
	//
	// The exact line type is determined based
	// on the category to update to and how it's routed to connect to other
	// page
	// elements.
	//
	// Possible values:
	//   "LINE_CATEGORY_UNSPECIFIED" - Unspecified line category.
	//   "STRAIGHT" - Straight connectors, including straight connector 1.
	//   "BENT" - Bent connectors, including bent connector 2 to 5.
	//   "CURVED" - Curved connectors, including curved connector 2 to 5.
	LineCategory string `json:"lineCategory,omitempty"`

	// ObjectId: The object ID of the line the update is applied to.
	//
	// Only a line with a category
	// indicating it is a "connector" can be updated.
	//
	// The line may be rerouted after updating its category.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LineCategory") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LineCategory") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateLineCategoryRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateLineCategoryRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateLinePropertiesRequest: Updates the properties of a Line.
type UpdateLinePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `lineProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the line solid fill color, set `fields`
	// to
	// "lineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// LineProperties: The line properties to update.
	LineProperties *LineProperties `json:"lineProperties,omitempty"`

	// ObjectId: The object ID of the line the update is applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateLinePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateLinePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementAltTextRequest: Updates the alt text title and/or
// description of a
// page element.
type UpdatePageElementAltTextRequest struct {
	// Description: The updated alt text description of the page element. If
	// unset the existing
	// value will be maintained. The description is exposed to screen
	// readers
	// and other accessibility interfaces. Only use human readable values
	// related
	// to the content of the page element.
	Description string `json:"description,omitempty"`

	// ObjectId: The object ID of the page element the updates are applied
	// to.
	ObjectId string `json:"objectId,omitempty"`

	// Title: The updated alt text title of the page element. If unset
	// the
	// existing value will be maintained. The title is exposed to screen
	// readers
	// and other accessibility interfaces. Only use human readable values
	// related
	// to the content of the page element.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementAltTextRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementAltTextRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementTransformRequest: Updates the transform of a page
// element.
//
// Updating the transform of a group will change the absolute transform
// of the
// page elements in that group, which can change their visual
// appearance. See
// the documentation for PageElement.transform for more details.
type UpdatePageElementTransformRequest struct {
	// ApplyMode: The apply mode of the transform update.
	//
	// Possible values:
	//   "APPLY_MODE_UNSPECIFIED" - Unspecified mode.
	//   "RELATIVE" - Applies the new AffineTransform matrix to the existing
	// one, and
	// replaces the existing one with the resulting concatenation.
	//   "ABSOLUTE" - Replaces the existing AffineTransform matrix with the
	// new one.
	ApplyMode string `json:"applyMode,omitempty"`

	// ObjectId: The object ID of the page element to update.
	ObjectId string `json:"objectId,omitempty"`

	// Transform: The input transform matrix used to update the page
	// element.
	Transform *AffineTransform `json:"transform,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApplyMode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApplyMode") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementTransformRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementTransformRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePageElementsZOrderRequest: Updates the Z-order of page
// elements. Z-order is an ordering of the elements
// on the page from back to front. The page element in the front may
// cover the
// elements that are behind it.
type UpdatePageElementsZOrderRequest struct {
	// Operation: The Z-order operation to apply on the page elements.
	//
	// When applying the operation on multiple page elements, the
	// relative
	// Z-orders within these page elements before the operation is
	// maintained.
	//
	// Possible values:
	//   "Z_ORDER_OPERATION_UNSPECIFIED" - Unspecified operation.
	//   "BRING_TO_FRONT" - Brings the page elements to the front of the
	// page.
	//   "BRING_FORWARD" - Brings the page elements forward on the page by
	// one element relative to the
	// forwardmost one in the specified page elements.
	//   "SEND_BACKWARD" - Sends the page elements backward on the page by
	// one element relative to the
	// furthest behind one in the specified page elements.
	//   "SEND_TO_BACK" - Sends the page elements to the back of the page.
	Operation string `json:"operation,omitempty"`

	// PageElementObjectIds: The object IDs of the page elements to
	// update.
	//
	// All the page elements must be on the same page and must not be
	// grouped.
	PageElementObjectIds []string `json:"pageElementObjectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Operation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Operation") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePageElementsZOrderRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePageElementsZOrderRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdatePagePropertiesRequest: Updates the properties of a Page.
type UpdatePagePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `pageProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the page background solid fill color, set
	// `fields`
	// to "pageBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the page the update is applied to.
	ObjectId string `json:"objectId,omitempty"`

	// PageProperties: The page properties to update.
	PageProperties *PageProperties `json:"pageProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdatePagePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdatePagePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateParagraphStyleRequest: Updates the styling for all of the
// paragraphs within a Shape or Table that
// overlap with the given text index range.
type UpdateParagraphStyleRequest struct {
	// CellLocation: The location of the cell in the table containing the
	// paragraph(s) to
	// style. If `object_id` refers to a table, `cell_location` must have a
	// value.
	// Otherwise, it must not.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `style` is implied
	// and
	// should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example, to update the paragraph alignment, set `fields`
	// to
	// "alignment".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape or table with the text to be
	// styled.
	ObjectId string `json:"objectId,omitempty"`

	// Style: The paragraph's style.
	Style *ParagraphStyle `json:"style,omitempty"`

	// TextRange: The range of text containing the paragraph(s) to style.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateParagraphStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateParagraphStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateShapePropertiesRequest: Update the properties of a Shape.
type UpdateShapePropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `shapeProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the shape background solid fill color, set
	// `fields`
	// to "shapeBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// ShapeProperties: The shape properties to update.
	ShapeProperties *ShapeProperties `json:"shapeProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateShapePropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateShapePropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateSlidesPositionRequest: Updates the position of slides in the
// presentation.
type UpdateSlidesPositionRequest struct {
	// InsertionIndex: The index where the slides should be inserted, based
	// on the slide
	// arrangement before the move takes place. Must be between zero and
	// the
	// number of slides in the presentation, inclusive.
	InsertionIndex int64 `json:"insertionIndex,omitempty"`

	// SlideObjectIds: The IDs of the slides in the presentation that should
	// be moved.
	// The slides in this list must be in existing presentation order,
	// without
	// duplicates.
	SlideObjectIds []string `json:"slideObjectIds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "InsertionIndex") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "InsertionIndex") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *UpdateSlidesPositionRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateSlidesPositionRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableBorderPropertiesRequest: Updates the properties of the
// table borders in a Table.
type UpdateTableBorderPropertiesRequest struct {
	// BorderPosition: The border position in the table range the updates
	// should apply to. If a
	// border position is not specified, the updates will apply to all
	// borders in
	// the table range.
	//
	// Possible values:
	//   "ALL" - All borders in the range.
	//   "BOTTOM" - Borders at the bottom of the range.
	//   "INNER" - Borders on the inside of the range.
	//   "INNER_HORIZONTAL" - Horizontal borders on the inside of the range.
	//   "INNER_VERTICAL" - Vertical borders on the inside of the range.
	//   "LEFT" - Borders at the left of the range.
	//   "OUTER" - Borders along the outside of the range.
	//   "RIGHT" - Borders at the right of the range.
	//   "TOP" - Borders at the top of the range.
	BorderPosition string `json:"borderPosition,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root
	// `tableBorderProperties` is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the table border solid fill color, set
	// `fields` to "tableBorderFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableBorderProperties: The table border properties to update.
	TableBorderProperties *TableBorderProperties `json:"tableBorderProperties,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates
	// are applied. If a table range is not specified, the updates will
	// apply to
	// the entire table.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BorderPosition") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BorderPosition") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableBorderPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableBorderPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableCellPropertiesRequest: Update the properties of a
// TableCell.
type UpdateTableCellPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableCellProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the table cell background solid fill color,
	// set
	// `fields` to "tableCellBackgroundFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableCellProperties: The table cell properties to update.
	TableCellProperties *TableCellProperties `json:"tableCellProperties,omitempty"`

	// TableRange: The table range representing the subset of the table to
	// which the updates
	// are applied. If a table range is not specified, the updates will
	// apply to
	// the entire table.
	TableRange *TableRange `json:"tableRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableCellPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableCellPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableColumnPropertiesRequest: Updates the properties of a Table
// column.
type UpdateTableColumnPropertiesRequest struct {
	// ColumnIndices: The list of zero-based indices specifying which
	// columns to update. If no
	// indices are provided, all columns in the table will be updated.
	ColumnIndices []int64 `json:"columnIndices,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root
	// `tableColumnProperties` is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the column width, set `fields` to
	// "column_width".
	//
	// If '"column_width"' is included in the field mask but the property is
	// left
	// unset, the column width will default to 406,400 EMU (32 points).
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// TableColumnProperties: The table column properties to update.
	//
	// If the value of `table_column_properties#column_width` in the request
	// is
	// less than 406,400 EMU (32 points), a 400 bad request error is
	// returned.
	TableColumnProperties *TableColumnProperties `json:"tableColumnProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ColumnIndices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ColumnIndices") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableColumnPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableColumnPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTableRowPropertiesRequest: Updates the properties of a Table
// row.
type UpdateTableRowPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `tableRowProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the minimum row height, set `fields`
	// to
	// "min_row_height".
	//
	// If '"min_row_height"' is included in the field mask but the property
	// is
	// left unset, the minimum row height will default to 0.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the table.
	ObjectId string `json:"objectId,omitempty"`

	// RowIndices: The list of zero-based indices specifying which rows to
	// update. If no
	// indices are provided, all rows in the table will be updated.
	RowIndices []int64 `json:"rowIndices,omitempty"`

	// TableRowProperties: The table row properties to update.
	TableRowProperties *TableRowProperties `json:"tableRowProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTableRowPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTableRowPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateTextStyleRequest: Update the styling of text in a Shape
// or
// Table.
type UpdateTextStyleRequest struct {
	// CellLocation: The location of the cell in the table containing the
	// text to style. If
	// `object_id` refers to a table, `cell_location` must have a
	// value.
	// Otherwise, it must not.
	CellLocation *TableCellLocation `json:"cellLocation,omitempty"`

	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `style` is implied
	// and
	// should not be specified. A single "*" can be used as short-hand
	// for
	// listing every field.
	//
	// For example, to update the text style to bold, set `fields` to
	// "bold".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the shape or table with the text to be
	// styled.
	ObjectId string `json:"objectId,omitempty"`

	// Style: The style(s) to set on the text.
	//
	// If the value for a particular style matches that of the parent, that
	// style
	// will be set to inherit.
	//
	// Certain text style changes may cause other changes meant to mirror
	// the
	// behavior of the Slides editor. See the documentation of
	// TextStyle for more information.
	Style *TextStyle `json:"style,omitempty"`

	// TextRange: The range of text to style.
	//
	// The range may be extended to include adjacent newlines.
	//
	// If the range fully contains a paragraph belonging to a list,
	// the
	// paragraph's bullet is also updated with the matching text style.
	TextRange *Range `json:"textRange,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CellLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CellLocation") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateTextStyleRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateTextStyleRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// UpdateVideoPropertiesRequest: Update the properties of a Video.
type UpdateVideoPropertiesRequest struct {
	// Fields: The fields that should be updated.
	//
	// At least one field must be specified. The root `videoProperties`
	// is
	// implied and should not be specified. A single "*" can be used
	// as
	// short-hand for listing every field.
	//
	// For example to update the video outline color, set `fields`
	// to
	// "outline.outlineFill.solidFill.color".
	//
	// To reset a property to its default value, include its field name in
	// the
	// field mask but leave the field itself unset.
	Fields string `json:"fields,omitempty"`

	// ObjectId: The object ID of the video the updates are applied to.
	ObjectId string `json:"objectId,omitempty"`

	// VideoProperties: The video properties to update.
	VideoProperties *VideoProperties `json:"videoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Fields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Fields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UpdateVideoPropertiesRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateVideoPropertiesRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Video: A PageElement kind representing a
// video.
type Video struct {
	// Id: The video source's unique identifier for this video.
	Id string `json:"id,omitempty"`

	// Source: The video source.
	//
	// Possible values:
	//   "SOURCE_UNSPECIFIED" - The video source is unspecified.
	//   "YOUTUBE" - The video source is YouTube.
	//   "DRIVE" - The video source is Google Drive.
	Source string `json:"source,omitempty"`

	// Url: An URL to a video. The URL is valid as long as the source video
	// exists and
	// sharing settings do not change.
	Url string `json:"url,omitempty"`

	// VideoProperties: The properties of the video.
	VideoProperties *VideoProperties `json:"videoProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Video) MarshalJSON() ([]byte, error) {
	type NoMethod Video
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// VideoProperties: The properties of the Video.
type VideoProperties struct {
	// AutoPlay: Whether to enable video autoplay when the page is displayed
	// in present
	// mode. Defaults to false.
	AutoPlay bool `json:"autoPlay,omitempty"`

	// End: The time at which to end playback, measured in seconds from the
	// beginning
	// of the video.
	// If set, the end time should be after the start time.
	// If not set or if you set this to a value that exceeds the video's
	// length,
	// the video will be played until its end.
	End int64 `json:"end,omitempty"`

	// Mute: Whether to mute the audio during video playback. Defaults to
	// false.
	Mute bool `json:"mute,omitempty"`

	// Outline: The outline of the video. The default outline matches the
	// defaults for new
	// videos created in the Slides editor.
	Outline *Outline `json:"outline,omitempty"`

	// Start: The time at which to start playback, measured in seconds from
	// the beginning
	// of the video.
	// If set, the start time should be before the end time.
	// If you set this to a value that exceeds the video's length in
	// seconds, the
	// video will be played from the last second.
	// If not set, the video will be played from the beginning.
	Start int64 `json:"start,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AutoPlay") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AutoPlay") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *VideoProperties) MarshalJSON() ([]byte, error) {
	type NoMethod VideoProperties
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WeightedFontFamily: Represents a font family and weight used to style
// a TextRun.
type WeightedFontFamily struct {
	// FontFamily: The font family of the text.
	//
	// The font family can be any font from the Font menu in Slides or
	// from
	// [Google Fonts] (https://fonts.google.com/). If the font name
	// is
	// unrecognized, the text is rendered in `Arial`.
	FontFamily string `json:"fontFamily,omitempty"`

	// Weight: The rendered weight of the text. This field can have any
	// value that is a
	// multiple of `100` between `100` and `900`, inclusive. This
	// range
	// corresponds to the numerical values described in the CSS
	// 2.1
	// Specification,
	// [section
	// 15.6](https://www.w3.org/TR/CSS21/fonts.html#font-boldness),
	// with non-numerical values disallowed. Weights greater than or equal
	// to
	// `700` are considered bold, and weights less than `700`are not bold.
	// The
	// default value is `400` ("normal").
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FontFamily") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FontFamily") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *WeightedFontFamily) MarshalJSON() ([]byte, error) {
	type NoMethod WeightedFontFamily
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WordArt: A PageElement kind representing
// word art.
type WordArt struct {
	// RenderedText: The text rendered as word art.
	RenderedText string `json:"renderedText,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RenderedText") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RenderedText") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *WordArt) MarshalJSON() ([]byte, error) {
	type NoMethod WordArt
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// WriteControl: Provides control over how write requests are executed.
type WriteControl struct {
	// RequiredRevisionId: The revision ID of the presentation required for
	// the write request. If
	// specified and the `required_revision_id` doesn't exactly match
	// the
	// presentation's current `revision_id`, the request will not be
	// processed and
	// will return a 400 bad request error.
	RequiredRevisionId string `json:"requiredRevisionId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RequiredRevisionId")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RequiredRevisionId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *WriteControl) MarshalJSON() ([]byte, error) {
	type NoMethod WriteControl
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "slides.presentations.batchUpdate":

type PresentationsBatchUpdateCall struct {
	s                              *Service
	presentationId                 string
	batchupdatepresentationrequest *BatchUpdatePresentationRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// BatchUpdate: Applies one or more updates to the presentation.
//
// Each request is validated before
// being applied. If any request is not valid, then the entire request
// will
// fail and nothing will be applied.
//
// Some requests have replies to
// give you some information about how they are applied. Other requests
// do
// not need to return information; these each return an empty reply.
// The order of replies matches that of the requests.
//
// For example, suppose you call batchUpdate with four updates, and only
// the
// third one returns information. The response would have two empty
// replies:
// the reply to the third request, and another empty reply, in that
// order.
//
// Because other users may be editing the presentation, the
// presentation
// might not exactly reflect your changes: your changes may
// be altered with respect to collaborator changes. If there are
// no
// collaborators, the presentation should reflect your changes. In any
// case,
// the updates in your request are guaranteed to be applied
// together
// atomically.
func (r *PresentationsService) BatchUpdate(presentationId string, batchupdatepresentationrequest *BatchUpdatePresentationRequest) *PresentationsBatchUpdateCall {
	c := &PresentationsBatchUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.batchupdatepresentationrequest = batchupdatepresentationrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsBatchUpdateCall) Fields(s ...googleapi.Field) *PresentationsBatchUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsBatchUpdateCall) Context(ctx context.Context) *PresentationsBatchUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsBatchUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsBatchUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.batchupdatepresentationrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}:batchUpdate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.batchUpdate" call.
// Exactly one of *BatchUpdatePresentationResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *BatchUpdatePresentationResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PresentationsBatchUpdateCall) Do(opts ...googleapi.CallOption) (*BatchUpdatePresentationResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BatchUpdatePresentationResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Applies one or more updates to the presentation.\n\nEach request is validated before\nbeing applied. If any request is not valid, then the entire request will\nfail and nothing will be applied.\n\nSome requests have replies to\ngive you some information about how they are applied. Other requests do\nnot need to return information; these each return an empty reply.\nThe order of replies matches that of the requests.\n\nFor example, suppose you call batchUpdate with four updates, and only the\nthird one returns information. The response would have two empty replies:\nthe reply to the third request, and another empty reply, in that order.\n\nBecause other users may be editing the presentation, the presentation\nmight not exactly reflect your changes: your changes may\nbe altered with respect to collaborator changes. If there are no\ncollaborators, the presentation should reflect your changes. In any case,\nthe updates in your request are guaranteed to be applied together\natomically.",
	//   "flatPath": "v1/presentations/{presentationId}:batchUpdate",
	//   "httpMethod": "POST",
	//   "id": "slides.presentations.batchUpdate",
	//   "parameterOrder": [
	//     "presentationId"
	//   ],
	//   "parameters": {
	//     "presentationId": {
	//       "description": "The presentation to apply the updates to.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}:batchUpdate",
	//   "request": {
	//     "$ref": "BatchUpdatePresentationRequest"
	//   },
	//   "response": {
	//     "$ref": "BatchUpdatePresentationResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/spreadsheets",
	//     "https://www.googleapis.com/auth/spreadsheets.readonly"
	//   ]
	// }

}

// method id "slides.presentations.create":

type PresentationsCreateCall struct {
	s            *Service
	presentation *Presentation
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Create: Creates a blank presentation using the title given in the
// request. If a
// `presentationId` is provided, it is used as the ID of the new
// presentation.
// Otherwise, a new ID is generated. Other fields in the request,
// including
// any provided content, are ignored.
// Returns the created presentation.
func (r *PresentationsService) Create(presentation *Presentation) *PresentationsCreateCall {
	c := &PresentationsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentation = presentation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsCreateCall) Fields(s ...googleapi.Field) *PresentationsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsCreateCall) Context(ctx context.Context) *PresentationsCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.presentation)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.create" call.
// Exactly one of *Presentation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Presentation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsCreateCall) Do(opts ...googleapi.CallOption) (*Presentation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Presentation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a blank presentation using the title given in the request. If a\n`presentationId` is provided, it is used as the ID of the new presentation.\nOtherwise, a new ID is generated. Other fields in the request, including\nany provided content, are ignored.\nReturns the created presentation.",
	//   "flatPath": "v1/presentations",
	//   "httpMethod": "POST",
	//   "id": "slides.presentations.create",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/presentations",
	//   "request": {
	//     "$ref": "Presentation"
	//   },
	//   "response": {
	//     "$ref": "Presentation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/presentations"
	//   ]
	// }

}

// method id "slides.presentations.get":

type PresentationsGetCall struct {
	s              *Service
	presentationId string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Gets the latest version of the specified presentation.
func (r *PresentationsService) Get(presentationId string) *PresentationsGetCall {
	c := &PresentationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsGetCall) Fields(s ...googleapi.Field) *PresentationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsGetCall) IfNoneMatch(entityTag string) *PresentationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsGetCall) Context(ctx context.Context) *PresentationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{+presentationId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.get" call.
// Exactly one of *Presentation or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Presentation.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsGetCall) Do(opts ...googleapi.CallOption) (*Presentation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Presentation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest version of the specified presentation.",
	//   "flatPath": "v1/presentations/{presentationsId}",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.get",
	//   "parameterOrder": [
	//     "presentationId"
	//   ],
	//   "parameters": {
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "pattern": "^[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{+presentationId}",
	//   "response": {
	//     "$ref": "Presentation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}

// method id "slides.presentations.pages.get":

type PresentationsPagesGetCall struct {
	s              *Service
	presentationId string
	pageObjectId   string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// Get: Gets the latest version of the specified page in the
// presentation.
func (r *PresentationsPagesService) Get(presentationId string, pageObjectId string) *PresentationsPagesGetCall {
	c := &PresentationsPagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.pageObjectId = pageObjectId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsPagesGetCall) Fields(s ...googleapi.Field) *PresentationsPagesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsPagesGetCall) IfNoneMatch(entityTag string) *PresentationsPagesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsPagesGetCall) Context(ctx context.Context) *PresentationsPagesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsPagesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsPagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}/pages/{pageObjectId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
		"pageObjectId":   c.pageObjectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.pages.get" call.
// Exactly one of *Page or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Page.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *PresentationsPagesGetCall) Do(opts ...googleapi.CallOption) (*Page, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Page{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the latest version of the specified page in the presentation.",
	//   "flatPath": "v1/presentations/{presentationId}/pages/{pageObjectId}",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.pages.get",
	//   "parameterOrder": [
	//     "presentationId",
	//     "pageObjectId"
	//   ],
	//   "parameters": {
	//     "pageObjectId": {
	//       "description": "The object ID of the page to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}/pages/{pageObjectId}",
	//   "response": {
	//     "$ref": "Page"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}

// method id "slides.presentations.pages.getThumbnail":

type PresentationsPagesGetThumbnailCall struct {
	s              *Service
	presentationId string
	pageObjectId   string
	urlParams_     gensupport.URLParams
	ifNoneMatch_   string
	ctx_           context.Context
	header_        http.Header
}

// GetThumbnail: Generates a thumbnail of the latest version of the
// specified page in the
// presentation and returns a URL to the thumbnail image.
//
// This request counts as an [expensive read request](/slides/limits)
// for
// quota purposes.
func (r *PresentationsPagesService) GetThumbnail(presentationId string, pageObjectId string) *PresentationsPagesGetThumbnailCall {
	c := &PresentationsPagesGetThumbnailCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.presentationId = presentationId
	c.pageObjectId = pageObjectId
	return c
}

// ThumbnailPropertiesMimeType sets the optional parameter
// "thumbnailProperties.mimeType": The optional mime type of the
// thumbnail image.
//
// If you don't specify the mime type, the default mime type will be
// PNG.
//
// Possible values:
//   "PNG"
func (c *PresentationsPagesGetThumbnailCall) ThumbnailPropertiesMimeType(thumbnailPropertiesMimeType string) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("thumbnailProperties.mimeType", thumbnailPropertiesMimeType)
	return c
}

// ThumbnailPropertiesThumbnailSize sets the optional parameter
// "thumbnailProperties.thumbnailSize": The optional thumbnail image
// size.
//
// If you don't specify the size, the server chooses a default size of
// the
// image.
//
// Possible values:
//   "THUMBNAIL_SIZE_UNSPECIFIED"
//   "LARGE"
//   "MEDIUM"
//   "SMALL"
func (c *PresentationsPagesGetThumbnailCall) ThumbnailPropertiesThumbnailSize(thumbnailPropertiesThumbnailSize string) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("thumbnailProperties.thumbnailSize", thumbnailPropertiesThumbnailSize)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PresentationsPagesGetThumbnailCall) Fields(s ...googleapi.Field) *PresentationsPagesGetThumbnailCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PresentationsPagesGetThumbnailCall) IfNoneMatch(entityTag string) *PresentationsPagesGetThumbnailCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PresentationsPagesGetThumbnailCall) Context(ctx context.Context) *PresentationsPagesGetThumbnailCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PresentationsPagesGetThumbnailCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PresentationsPagesGetThumbnailCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"presentationId": c.presentationId,
		"pageObjectId":   c.pageObjectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "slides.presentations.pages.getThumbnail" call.
// Exactly one of *Thumbnail or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Thumbnail.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PresentationsPagesGetThumbnailCall) Do(opts ...googleapi.CallOption) (*Thumbnail, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Thumbnail{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates a thumbnail of the latest version of the specified page in the\npresentation and returns a URL to the thumbnail image.\n\nThis request counts as an [expensive read request](/slides/limits) for\nquota purposes.",
	//   "flatPath": "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail",
	//   "httpMethod": "GET",
	//   "id": "slides.presentations.pages.getThumbnail",
	//   "parameterOrder": [
	//     "presentationId",
	//     "pageObjectId"
	//   ],
	//   "parameters": {
	//     "pageObjectId": {
	//       "description": "The object ID of the page whose thumbnail to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "presentationId": {
	//       "description": "The ID of the presentation to retrieve.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "thumbnailProperties.mimeType": {
	//       "description": "The optional mime type of the thumbnail image.\n\nIf you don't specify the mime type, the default mime type will be PNG.",
	//       "enum": [
	//         "PNG"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "thumbnailProperties.thumbnailSize": {
	//       "description": "The optional thumbnail image size.\n\nIf you don't specify the size, the server chooses a default size of the\nimage.",
	//       "enum": [
	//         "THUMBNAIL_SIZE_UNSPECIFIED",
	//         "LARGE",
	//         "MEDIUM",
	//         "SMALL"
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/presentations/{presentationId}/pages/{pageObjectId}/thumbnail",
	//   "response": {
	//     "$ref": "Thumbnail"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/drive",
	//     "https://www.googleapis.com/auth/drive.file",
	//     "https://www.googleapis.com/auth/drive.readonly",
	//     "https://www.googleapis.com/auth/presentations",
	//     "https://www.googleapis.com/auth/presentations.readonly"
	//   ]
	// }

}
