// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.

package fetch

import (
	json "encoding/json"
	io "github.com/chromedp/cdproto/io"
	network "github.com/chromedp/cdproto/network"
	easyjson "github.com/mailru/easyjson"
	jlexer "github.com/mailru/easyjson/jlexer"
	jwriter "github.com/mailru/easyjson/jwriter"
)

// suppress unused package warning
var (
	_ *json.RawMessage
	_ *jlexer.Lexer
	_ *jwriter.Writer
	_ easyjson.Marshaler
)

func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch(in *jlexer.Lexer, out *TakeResponseBodyAsStreamReturns) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "stream":
			out.Stream = io.StreamHandle(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch(out *jwriter.Writer, in TakeResponseBodyAsStreamReturns) {
	out.RawByte('{')
	first := true
	_ = first
	if in.Stream != "" {
		const prefix string = ",\"stream\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Stream))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v TakeResponseBodyAsStreamReturns) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v TakeResponseBodyAsStreamReturns) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *TakeResponseBodyAsStreamReturns) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *TakeResponseBodyAsStreamReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch1(in *jlexer.Lexer, out *TakeResponseBodyAsStreamParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch1(out *jwriter.Writer, in TakeResponseBodyAsStreamParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v TakeResponseBodyAsStreamParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch1(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v TakeResponseBodyAsStreamParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch1(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *TakeResponseBodyAsStreamParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch1(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *TakeResponseBodyAsStreamParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch1(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch2(in *jlexer.Lexer, out *RequestPattern) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "urlPattern":
			out.URLPattern = string(in.String())
		case "resourceType":
			(out.ResourceType).UnmarshalEasyJSON(in)
		case "requestStage":
			(out.RequestStage).UnmarshalEasyJSON(in)
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch2(out *jwriter.Writer, in RequestPattern) {
	out.RawByte('{')
	first := true
	_ = first
	if in.URLPattern != "" {
		const prefix string = ",\"urlPattern\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.URLPattern))
	}
	if in.ResourceType != "" {
		const prefix string = ",\"resourceType\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.ResourceType).MarshalEasyJSON(out)
	}
	if in.RequestStage != "" {
		const prefix string = ",\"requestStage\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.RequestStage).MarshalEasyJSON(out)
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v RequestPattern) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch2(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v RequestPattern) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch2(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *RequestPattern) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch2(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *RequestPattern) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch2(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch3(in *jlexer.Lexer, out *HeaderEntry) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "name":
			out.Name = string(in.String())
		case "value":
			out.Value = string(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch3(out *jwriter.Writer, in HeaderEntry) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"name\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Name))
	}
	{
		const prefix string = ",\"value\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Value))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v HeaderEntry) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch3(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v HeaderEntry) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch3(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *HeaderEntry) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch3(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *HeaderEntry) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch3(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch4(in *jlexer.Lexer, out *GetResponseBodyReturns) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "body":
			out.Body = string(in.String())
		case "base64Encoded":
			out.Base64encoded = bool(in.Bool())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch4(out *jwriter.Writer, in GetResponseBodyReturns) {
	out.RawByte('{')
	first := true
	_ = first
	if in.Body != "" {
		const prefix string = ",\"body\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Body))
	}
	if in.Base64encoded {
		const prefix string = ",\"base64Encoded\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.Bool(bool(in.Base64encoded))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v GetResponseBodyReturns) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch4(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v GetResponseBodyReturns) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch4(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *GetResponseBodyReturns) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch4(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *GetResponseBodyReturns) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch4(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch5(in *jlexer.Lexer, out *GetResponseBodyParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch5(out *jwriter.Writer, in GetResponseBodyParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v GetResponseBodyParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch5(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v GetResponseBodyParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch5(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *GetResponseBodyParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch5(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *GetResponseBodyParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch5(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch6(in *jlexer.Lexer, out *FulfillRequestParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "responseCode":
			out.ResponseCode = int64(in.Int64())
		case "responseHeaders":
			if in.IsNull() {
				in.Skip()
				out.ResponseHeaders = nil
			} else {
				in.Delim('[')
				if out.ResponseHeaders == nil {
					if !in.IsDelim(']') {
						out.ResponseHeaders = make([]*HeaderEntry, 0, 8)
					} else {
						out.ResponseHeaders = []*HeaderEntry{}
					}
				} else {
					out.ResponseHeaders = (out.ResponseHeaders)[:0]
				}
				for !in.IsDelim(']') {
					var v1 *HeaderEntry
					if in.IsNull() {
						in.Skip()
						v1 = nil
					} else {
						if v1 == nil {
							v1 = new(HeaderEntry)
						}
						(*v1).UnmarshalEasyJSON(in)
					}
					out.ResponseHeaders = append(out.ResponseHeaders, v1)
					in.WantComma()
				}
				in.Delim(']')
			}
		case "body":
			out.Body = string(in.String())
		case "responsePhrase":
			out.ResponsePhrase = string(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch6(out *jwriter.Writer, in FulfillRequestParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	{
		const prefix string = ",\"responseCode\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.Int64(int64(in.ResponseCode))
	}
	{
		const prefix string = ",\"responseHeaders\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		if in.ResponseHeaders == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
			out.RawString("null")
		} else {
			out.RawByte('[')
			for v2, v3 := range in.ResponseHeaders {
				if v2 > 0 {
					out.RawByte(',')
				}
				if v3 == nil {
					out.RawString("null")
				} else {
					(*v3).MarshalEasyJSON(out)
				}
			}
			out.RawByte(']')
		}
	}
	if in.Body != "" {
		const prefix string = ",\"body\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Body))
	}
	if in.ResponsePhrase != "" {
		const prefix string = ",\"responsePhrase\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.ResponsePhrase))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v FulfillRequestParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch6(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v FulfillRequestParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch6(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *FulfillRequestParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch6(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *FulfillRequestParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch6(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch7(in *jlexer.Lexer, out *FailRequestParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "errorReason":
			(out.ErrorReason).UnmarshalEasyJSON(in)
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch7(out *jwriter.Writer, in FailRequestParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	{
		const prefix string = ",\"errorReason\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.ErrorReason).MarshalEasyJSON(out)
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v FailRequestParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch7(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v FailRequestParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch7(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *FailRequestParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch7(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *FailRequestParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch7(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch8(in *jlexer.Lexer, out *EventRequestPaused) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "request":
			if in.IsNull() {
				in.Skip()
				out.Request = nil
			} else {
				if out.Request == nil {
					out.Request = new(network.Request)
				}
				(*out.Request).UnmarshalEasyJSON(in)
			}
		case "frameId":
			(out.FrameID).UnmarshalEasyJSON(in)
		case "resourceType":
			(out.ResourceType).UnmarshalEasyJSON(in)
		case "responseErrorReason":
			(out.ResponseErrorReason).UnmarshalEasyJSON(in)
		case "responseStatusCode":
			out.ResponseStatusCode = int64(in.Int64())
		case "responseHeaders":
			if in.IsNull() {
				in.Skip()
				out.ResponseHeaders = nil
			} else {
				in.Delim('[')
				if out.ResponseHeaders == nil {
					if !in.IsDelim(']') {
						out.ResponseHeaders = make([]*HeaderEntry, 0, 8)
					} else {
						out.ResponseHeaders = []*HeaderEntry{}
					}
				} else {
					out.ResponseHeaders = (out.ResponseHeaders)[:0]
				}
				for !in.IsDelim(']') {
					var v4 *HeaderEntry
					if in.IsNull() {
						in.Skip()
						v4 = nil
					} else {
						if v4 == nil {
							v4 = new(HeaderEntry)
						}
						(*v4).UnmarshalEasyJSON(in)
					}
					out.ResponseHeaders = append(out.ResponseHeaders, v4)
					in.WantComma()
				}
				in.Delim(']')
			}
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch8(out *jwriter.Writer, in EventRequestPaused) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	{
		const prefix string = ",\"request\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		if in.Request == nil {
			out.RawString("null")
		} else {
			(*in.Request).MarshalEasyJSON(out)
		}
	}
	{
		const prefix string = ",\"frameId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.FrameID))
	}
	{
		const prefix string = ",\"resourceType\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.ResourceType).MarshalEasyJSON(out)
	}
	if in.ResponseErrorReason != "" {
		const prefix string = ",\"responseErrorReason\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.ResponseErrorReason).MarshalEasyJSON(out)
	}
	if in.ResponseStatusCode != 0 {
		const prefix string = ",\"responseStatusCode\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.Int64(int64(in.ResponseStatusCode))
	}
	if len(in.ResponseHeaders) != 0 {
		const prefix string = ",\"responseHeaders\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		{
			out.RawByte('[')
			for v5, v6 := range in.ResponseHeaders {
				if v5 > 0 {
					out.RawByte(',')
				}
				if v6 == nil {
					out.RawString("null")
				} else {
					(*v6).MarshalEasyJSON(out)
				}
			}
			out.RawByte(']')
		}
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v EventRequestPaused) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch8(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventRequestPaused) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch8(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventRequestPaused) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch8(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventRequestPaused) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch8(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch9(in *jlexer.Lexer, out *EventAuthRequired) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "request":
			if in.IsNull() {
				in.Skip()
				out.Request = nil
			} else {
				if out.Request == nil {
					out.Request = new(network.Request)
				}
				(*out.Request).UnmarshalEasyJSON(in)
			}
		case "frameId":
			(out.FrameID).UnmarshalEasyJSON(in)
		case "resourceType":
			(out.ResourceType).UnmarshalEasyJSON(in)
		case "authChallenge":
			if in.IsNull() {
				in.Skip()
				out.AuthChallenge = nil
			} else {
				if out.AuthChallenge == nil {
					out.AuthChallenge = new(AuthChallenge)
				}
				(*out.AuthChallenge).UnmarshalEasyJSON(in)
			}
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch9(out *jwriter.Writer, in EventAuthRequired) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	{
		const prefix string = ",\"request\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		if in.Request == nil {
			out.RawString("null")
		} else {
			(*in.Request).MarshalEasyJSON(out)
		}
	}
	{
		const prefix string = ",\"frameId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.FrameID))
	}
	{
		const prefix string = ",\"resourceType\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.ResourceType).MarshalEasyJSON(out)
	}
	{
		const prefix string = ",\"authChallenge\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		if in.AuthChallenge == nil {
			out.RawString("null")
		} else {
			(*in.AuthChallenge).MarshalEasyJSON(out)
		}
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v EventAuthRequired) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch9(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EventAuthRequired) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch9(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *EventAuthRequired) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch9(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EventAuthRequired) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch9(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch10(in *jlexer.Lexer, out *EnableParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "patterns":
			if in.IsNull() {
				in.Skip()
				out.Patterns = nil
			} else {
				in.Delim('[')
				if out.Patterns == nil {
					if !in.IsDelim(']') {
						out.Patterns = make([]*RequestPattern, 0, 8)
					} else {
						out.Patterns = []*RequestPattern{}
					}
				} else {
					out.Patterns = (out.Patterns)[:0]
				}
				for !in.IsDelim(']') {
					var v7 *RequestPattern
					if in.IsNull() {
						in.Skip()
						v7 = nil
					} else {
						if v7 == nil {
							v7 = new(RequestPattern)
						}
						(*v7).UnmarshalEasyJSON(in)
					}
					out.Patterns = append(out.Patterns, v7)
					in.WantComma()
				}
				in.Delim(']')
			}
		case "handleAuthRequests":
			out.HandleAuthRequests = bool(in.Bool())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch10(out *jwriter.Writer, in EnableParams) {
	out.RawByte('{')
	first := true
	_ = first
	if len(in.Patterns) != 0 {
		const prefix string = ",\"patterns\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		{
			out.RawByte('[')
			for v8, v9 := range in.Patterns {
				if v8 > 0 {
					out.RawByte(',')
				}
				if v9 == nil {
					out.RawString("null")
				} else {
					(*v9).MarshalEasyJSON(out)
				}
			}
			out.RawByte(']')
		}
	}
	if in.HandleAuthRequests {
		const prefix string = ",\"handleAuthRequests\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.Bool(bool(in.HandleAuthRequests))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v EnableParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch10(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v EnableParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch10(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *EnableParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch10(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *EnableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch10(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch11(in *jlexer.Lexer, out *DisableParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch11(out *jwriter.Writer, in DisableParams) {
	out.RawByte('{')
	first := true
	_ = first
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v DisableParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch11(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v DisableParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch11(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *DisableParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch11(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *DisableParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch11(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch12(in *jlexer.Lexer, out *ContinueWithAuthParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "authChallengeResponse":
			if in.IsNull() {
				in.Skip()
				out.AuthChallengeResponse = nil
			} else {
				if out.AuthChallengeResponse == nil {
					out.AuthChallengeResponse = new(AuthChallengeResponse)
				}
				(*out.AuthChallengeResponse).UnmarshalEasyJSON(in)
			}
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch12(out *jwriter.Writer, in ContinueWithAuthParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	{
		const prefix string = ",\"authChallengeResponse\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		if in.AuthChallengeResponse == nil {
			out.RawString("null")
		} else {
			(*in.AuthChallengeResponse).MarshalEasyJSON(out)
		}
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v ContinueWithAuthParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch12(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ContinueWithAuthParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch12(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *ContinueWithAuthParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch12(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ContinueWithAuthParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch12(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch13(in *jlexer.Lexer, out *ContinueRequestParams) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "requestId":
			out.RequestID = RequestID(in.String())
		case "url":
			out.URL = string(in.String())
		case "method":
			out.Method = string(in.String())
		case "postData":
			out.PostData = string(in.String())
		case "headers":
			if in.IsNull() {
				in.Skip()
				out.Headers = nil
			} else {
				in.Delim('[')
				if out.Headers == nil {
					if !in.IsDelim(']') {
						out.Headers = make([]*HeaderEntry, 0, 8)
					} else {
						out.Headers = []*HeaderEntry{}
					}
				} else {
					out.Headers = (out.Headers)[:0]
				}
				for !in.IsDelim(']') {
					var v10 *HeaderEntry
					if in.IsNull() {
						in.Skip()
						v10 = nil
					} else {
						if v10 == nil {
							v10 = new(HeaderEntry)
						}
						(*v10).UnmarshalEasyJSON(in)
					}
					out.Headers = append(out.Headers, v10)
					in.WantComma()
				}
				in.Delim(']')
			}
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch13(out *jwriter.Writer, in ContinueRequestParams) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"requestId\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.RequestID))
	}
	if in.URL != "" {
		const prefix string = ",\"url\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.URL))
	}
	if in.Method != "" {
		const prefix string = ",\"method\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Method))
	}
	if in.PostData != "" {
		const prefix string = ",\"postData\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.PostData))
	}
	if len(in.Headers) != 0 {
		const prefix string = ",\"headers\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		{
			out.RawByte('[')
			for v11, v12 := range in.Headers {
				if v11 > 0 {
					out.RawByte(',')
				}
				if v12 == nil {
					out.RawString("null")
				} else {
					(*v12).MarshalEasyJSON(out)
				}
			}
			out.RawByte(']')
		}
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v ContinueRequestParams) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch13(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ContinueRequestParams) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch13(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *ContinueRequestParams) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch13(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ContinueRequestParams) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch13(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch14(in *jlexer.Lexer, out *AuthChallengeResponse) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "response":
			(out.Response).UnmarshalEasyJSON(in)
		case "username":
			out.Username = string(in.String())
		case "password":
			out.Password = string(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch14(out *jwriter.Writer, in AuthChallengeResponse) {
	out.RawByte('{')
	first := true
	_ = first
	{
		const prefix string = ",\"response\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.Response).MarshalEasyJSON(out)
	}
	if in.Username != "" {
		const prefix string = ",\"username\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Username))
	}
	if in.Password != "" {
		const prefix string = ",\"password\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Password))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v AuthChallengeResponse) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch14(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v AuthChallengeResponse) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch14(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *AuthChallengeResponse) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch14(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *AuthChallengeResponse) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch14(l, v)
}
func easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch15(in *jlexer.Lexer, out *AuthChallenge) {
	isTopLevel := in.IsStart()
	if in.IsNull() {
		if isTopLevel {
			in.Consumed()
		}
		in.Skip()
		return
	}
	in.Delim('{')
	for !in.IsDelim('}') {
		key := in.UnsafeString()
		in.WantColon()
		if in.IsNull() {
			in.Skip()
			in.WantComma()
			continue
		}
		switch key {
		case "source":
			(out.Source).UnmarshalEasyJSON(in)
		case "origin":
			out.Origin = string(in.String())
		case "scheme":
			out.Scheme = string(in.String())
		case "realm":
			out.Realm = string(in.String())
		default:
			in.SkipRecursive()
		}
		in.WantComma()
	}
	in.Delim('}')
	if isTopLevel {
		in.Consumed()
	}
}
func easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch15(out *jwriter.Writer, in AuthChallenge) {
	out.RawByte('{')
	first := true
	_ = first
	if in.Source != "" {
		const prefix string = ",\"source\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		(in.Source).MarshalEasyJSON(out)
	}
	{
		const prefix string = ",\"origin\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Origin))
	}
	{
		const prefix string = ",\"scheme\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Scheme))
	}
	{
		const prefix string = ",\"realm\":"
		if first {
			first = false
			out.RawString(prefix[1:])
		} else {
			out.RawString(prefix)
		}
		out.String(string(in.Realm))
	}
	out.RawByte('}')
}

// MarshalJSON supports json.Marshaler interface
func (v AuthChallenge) MarshalJSON() ([]byte, error) {
	w := jwriter.Writer{}
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch15(&w, v)
	return w.Buffer.BuildBytes(), w.Error
}

// MarshalEasyJSON supports easyjson.Marshaler interface
func (v AuthChallenge) MarshalEasyJSON(w *jwriter.Writer) {
	easyjsonC5a4559bEncodeGithubComChromedpCdprotoFetch15(w, v)
}

// UnmarshalJSON supports json.Unmarshaler interface
func (v *AuthChallenge) UnmarshalJSON(data []byte) error {
	r := jlexer.Lexer{Data: data}
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch15(&r, v)
	return r.Error()
}

// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *AuthChallenge) UnmarshalEasyJSON(l *jlexer.Lexer) {
	easyjsonC5a4559bDecodeGithubComChromedpCdprotoFetch15(l, v)
}
